├── .gitignore ├── Kconfig ├── LICENSE ├── Makefile ├── exfat.h ├── exfat_api.c ├── exfat_api.h ├── exfat_blkdev.c ├── exfat_blkdev.h ├── exfat_cache.c ├── exfat_cache.h ├── exfat_data.c ├── exfat_data.h ├── exfat_global.c ├── exfat_global.h ├── exfat_misc.c ├── exfat_nls.c ├── exfat_nls.h ├── exfat_oal.c ├── exfat_oal.h ├── exfat_part.h ├── exfat_super.c ├── exfat_super.h ├── exfat_upcase.c └── exfat_xattr.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.cmd 2 | *.ko 3 | *.mod.c 4 | modules.order 5 | Module.symvers 6 | *.o 7 | .tmp_versions 8 | -------------------------------------------------------------------------------- /Kconfig: -------------------------------------------------------------------------------- 1 | config EXFAT_FS 2 | tristate "exFAT fs support" 3 | default m 4 | select NLS 5 | select NLS_UTF8 6 | help 7 | Say Y or M here to include support for the exFAT filesystem. 8 | 9 | To compile this as a module, choose M: the module will be called 10 | exfat. 11 | 12 | config EXFAT_DEFAULT_CODEPAGE 13 | int "Default codepage for exFAT" 14 | depends on EXFAT_FS 15 | default 437 16 | help 17 | This option should be set to the codepage of your exFAT filesystems. 18 | It can be overridden with the "codepage" mount option. 19 | 20 | config EXFAT_DEFAULT_IOCHARSET 21 | string "Default iocharset for exFAT" 22 | depends on EXFAT_FS 23 | default "utf8" 24 | help 25 | Set this to the default input/output character set you'd 26 | like exFAT to use. It should probably match the character set 27 | that most of your exFAT filesystems use, and can be overridden 28 | with the "iocharset" mount option for exFAT filesystems. 29 | 30 | In most cases, this should be set to utf8. 31 | 32 | Enable any character sets you need in File Systems/Native Language 33 | Support. 34 | 35 | config EXFAT_VIRTUAL_XATTR 36 | bool "Virtual xattr support for exFAT" 37 | depends on EXFAT_FS && SECURITY_SELINUX 38 | help 39 | Say Y here to enable virtual xattr support, allowing you to 40 | set a default SELinux label for files on the exFAT filesystem. 41 | 42 | config EXFAT_VIRTUAL_XATTR_SELINUX_LABEL 43 | string "Default SELinux label string for exFAT" 44 | depends on EXFAT_VIRTUAL_XATTR 45 | default "u:object_r:sdcard_external:s0" 46 | help 47 | Set this to the default string for exFAT SELinux label. 48 | 49 | config EXFAT_COMPAT_TUXERA 50 | bool "Tuxera compatibility for exFAT" 51 | depends on EXFAT_FS 52 | help 53 | Say Y here to have the exFAT driver also register as texfat 54 | for drop-in replacement on systems previously using 55 | Tuxera's commercial exFAT driver. 56 | 57 | If you are building exFAT as a module, this will change 58 | the module's name to texfat. 59 | 60 | config EXFAT_COMPAT_UFSD 61 | bool "Paragon UFSD compatibility for exFAT" 62 | depends on EXFAT_FS 63 | help 64 | Say Y here to have the exFAT driver also register as ufsd 65 | for drop-in replacement on systems previously using 66 | Paragon's commercial UFSD exFAT driver. 67 | 68 | config EXFAT_DEBUG 69 | bool "Debugging support for exFAT" 70 | depends on EXFAT_FS 71 | help 72 | Say Y here to enable debugging in exFAT driver. 73 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # exFAT filesystem driver rules 2 | 3 | exfat := exfat 4 | 5 | ifeq ($(CONFIG_EXFAT_COMPAT_TUXERA),y) 6 | exfat := texfat 7 | endif 8 | 9 | obj-$(CONFIG_EXFAT_FS) := $(exfat).o 10 | 11 | $(exfat)-y := exfat_super.o exfat_misc.o exfat_api.o \ 12 | exfat_blkdev.o exfat_cache.o \ 13 | exfat_data.o exfat_global.o exfat_nls.o \ 14 | exfat_oal.o exfat_upcase.o exfat_xattr.o 15 | 16 | ccflags-y += -DEXFAT_VERSION=\"1.2.24\" 17 | -------------------------------------------------------------------------------- /exfat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation; either version 2 7 | * of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | #ifndef _EXFAT_H 20 | #define _EXFAT_H 21 | 22 | #include 23 | 24 | #include "exfat_global.h" 25 | 26 | #include "exfat_data.h" 27 | #include "exfat_oal.h" 28 | 29 | #include "exfat_blkdev.h" 30 | #include "exfat_cache.h" 31 | #include "exfat_nls.h" 32 | #include "exfat_api.h" 33 | #include "exfat_cache.h" 34 | 35 | #ifdef __cplusplus 36 | extern "C" { 37 | #endif 38 | 39 | #ifdef CONFIG_EXFAT_DEBUG 40 | #define EXFAT_IOC_GET_DEBUGFLAGS _IOR('f', 100, long) 41 | #define EXFAT_IOC_SET_DEBUGFLAGS _IOW('f', 101, long) 42 | 43 | #define EXFAT_DEBUGFLAGS_INVALID_UMOUNT 0x01 44 | #define EXFAT_DEBUGFLAGS_ERROR_RW 0x02 45 | #endif 46 | 47 | #define MAX_VOLUME 4 48 | 49 | #define DENTRY_SIZE 32 50 | #define DENTRY_SIZE_BITS 5 51 | 52 | #define PBR_SIGNATURE 0xAA55 53 | #define EXT_SIGNATURE 0xAA550000 54 | #define VOL_LABEL "NO NAME " 55 | #define OEM_NAME "MSWIN4.1" 56 | #define STR_FAT12 "FAT12 " 57 | #define STR_FAT16 "FAT16 " 58 | #define STR_FAT32 "FAT32 " 59 | #define STR_EXFAT "EXFAT " 60 | #define VOL_CLEAN 0x0000 61 | #define VOL_DIRTY 0x0002 62 | 63 | #define FAT12_THRESHOLD 4087 64 | #define FAT16_THRESHOLD 65527 65 | #define FAT32_THRESHOLD 268435457 66 | #define EXFAT_THRESHOLD 268435457 67 | 68 | #define TYPE_UNUSED 0x0000 69 | #define TYPE_DELETED 0x0001 70 | #define TYPE_INVALID 0x0002 71 | #define TYPE_CRITICAL_PRI 0x0100 72 | #define TYPE_BITMAP 0x0101 73 | #define TYPE_UPCASE 0x0102 74 | #define TYPE_VOLUME 0x0103 75 | #define TYPE_DIR 0x0104 76 | #define TYPE_FILE 0x011F 77 | #define TYPE_SYMLINK 0x015F 78 | #define TYPE_CRITICAL_SEC 0x0200 79 | #define TYPE_STREAM 0x0201 80 | #define TYPE_EXTEND 0x0202 81 | #define TYPE_ACL 0x0203 82 | #define TYPE_BENIGN_PRI 0x0400 83 | #define TYPE_GUID 0x0401 84 | #define TYPE_PADDING 0x0402 85 | #define TYPE_ACLTAB 0x0403 86 | #define TYPE_BENIGN_SEC 0x0800 87 | #define TYPE_ALL 0x0FFF 88 | 89 | #define TM_CREATE 0 90 | #define TM_MODIFY 1 91 | #define TM_ACCESS 2 92 | 93 | #define CS_DIR_ENTRY 0 94 | #define CS_PBR_SECTOR 1 95 | #define CS_DEFAULT 2 96 | 97 | #define DIR_DELETED 0xFFFF0321 98 | 99 | #define CLUSTER_16(x) ((UINT16)(x)) 100 | #define CLUSTER_32(x) ((UINT32)(x)) 101 | 102 | #define START_SECTOR(x) \ 103 | ((((SECTOR)((x)-2)) << p_fs->sectors_per_clu_bits) + p_fs->data_start_sector) 104 | 105 | #define IS_LAST_SECTOR_IN_CLUSTER(sec) \ 106 | ((((sec) - p_fs->data_start_sector + 1) & ((1 << p_fs->sectors_per_clu_bits) -1)) == 0) 107 | 108 | #define GET_CLUSTER_FROM_SECTOR(sec) \ 109 | (CLUSTER_32((((sec) - p_fs->data_start_sector) >> p_fs->sectors_per_clu_bits) +2)) 110 | 111 | #define GET16(p_src) \ 112 | ( ((UINT16)(p_src)[0]) | (((UINT16)(p_src)[1]) << 8) ) 113 | #define GET32(p_src) \ 114 | ( ((UINT32)(p_src)[0]) | (((UINT32)(p_src)[1]) << 8) | \ 115 | (((UINT32)(p_src)[2]) << 16) | (((UINT32)(p_src)[3]) << 24) ) 116 | #define GET64(p_src) \ 117 | ( ((UINT64)(p_src)[0]) | (((UINT64)(p_src)[1]) << 8) | \ 118 | (((UINT64)(p_src)[2]) << 16) | (((UINT64)(p_src)[3]) << 24) | \ 119 | (((UINT64)(p_src)[4]) << 32) | (((UINT64)(p_src)[5]) << 40) | \ 120 | (((UINT64)(p_src)[6]) << 48) | (((UINT64)(p_src)[7]) << 56) ) 121 | 122 | 123 | #define SET16(p_dst,src) \ 124 | do { \ 125 | (p_dst)[0]=(UINT8)(src); \ 126 | (p_dst)[1]=(UINT8)(((UINT16)(src)) >> 8); \ 127 | } while (0) 128 | #define SET32(p_dst,src) \ 129 | do { \ 130 | (p_dst)[0]=(UINT8)(src); \ 131 | (p_dst)[1]=(UINT8)(((UINT32)(src)) >> 8); \ 132 | (p_dst)[2]=(UINT8)(((UINT32)(src)) >> 16); \ 133 | (p_dst)[3]=(UINT8)(((UINT32)(src)) >> 24); \ 134 | } while (0) 135 | #define SET64(p_dst,src) \ 136 | do { \ 137 | (p_dst)[0]=(UINT8)(src); \ 138 | (p_dst)[1]=(UINT8)(((UINT64)(src)) >> 8); \ 139 | (p_dst)[2]=(UINT8)(((UINT64)(src)) >> 16); \ 140 | (p_dst)[3]=(UINT8)(((UINT64)(src)) >> 24); \ 141 | (p_dst)[4]=(UINT8)(((UINT64)(src)) >> 32); \ 142 | (p_dst)[5]=(UINT8)(((UINT64)(src)) >> 40); \ 143 | (p_dst)[6]=(UINT8)(((UINT64)(src)) >> 48); \ 144 | (p_dst)[7]=(UINT8)(((UINT64)(src)) >> 56); \ 145 | } while (0) 146 | 147 | #ifdef __LITTLE_ENDIAN 148 | #define GET16_A(p_src) (*((UINT16 *)(p_src))) 149 | #define GET32_A(p_src) (*((UINT32 *)(p_src))) 150 | #define GET64_A(p_src) (*((UINT64 *)(p_src))) 151 | #define SET16_A(p_dst,src) *((UINT16 *)(p_dst)) = (UINT16)(src) 152 | #define SET32_A(p_dst,src) *((UINT32 *)(p_dst)) = (UINT32)(src) 153 | #define SET64_A(p_dst,src) *((UINT64 *)(p_dst)) = (UINT64)(src) 154 | #else 155 | #define GET16_A(p_src) GET16(p_src) 156 | #define GET32_A(p_src) GET32(p_src) 157 | #define GET64_A(p_src) GET64(p_src) 158 | #define SET16_A(p_dst,src) SET16(p_dst, src) 159 | #define SET32_A(p_dst,src) SET32(p_dst, src) 160 | #define SET64_A(p_dst,src) SET64(p_dst, src) 161 | #endif 162 | 163 | #define HIGH_INDEX_BIT (8) 164 | #define HIGH_INDEX_MASK (0xFF00) 165 | #define LOW_INDEX_BIT (16-HIGH_INDEX_BIT) 166 | #define UTBL_ROW_COUNT (1<> LOW_INDEX_BIT; 172 | } 173 | static inline UINT16 get_row_index(UINT16 i) 174 | { 175 | return i & ~HIGH_INDEX_MASK; 176 | } 177 | 178 | typedef struct { 179 | UINT8 jmp_boot[3]; 180 | UINT8 oem_name[8]; 181 | UINT8 bpb[109]; 182 | UINT8 boot_code[390]; 183 | UINT8 signature[2]; 184 | } PBR_SECTOR_T; 185 | 186 | typedef struct { 187 | UINT8 sector_size[2]; 188 | UINT8 sectors_per_clu; 189 | UINT8 num_reserved[2]; 190 | UINT8 num_fats; 191 | UINT8 num_root_entries[2]; 192 | UINT8 num_sectors[2]; 193 | UINT8 media_type; 194 | UINT8 num_fat_sectors[2]; 195 | UINT8 sectors_in_track[2]; 196 | UINT8 num_heads[2]; 197 | UINT8 num_hid_sectors[4]; 198 | UINT8 num_huge_sectors[4]; 199 | 200 | UINT8 phy_drv_no; 201 | UINT8 reserved; 202 | UINT8 ext_signature; 203 | UINT8 vol_serial[4]; 204 | UINT8 vol_label[11]; 205 | UINT8 vol_type[8]; 206 | } BPB16_T; 207 | 208 | typedef struct { 209 | UINT8 sector_size[2]; 210 | UINT8 sectors_per_clu; 211 | UINT8 num_reserved[2]; 212 | UINT8 num_fats; 213 | UINT8 num_root_entries[2]; 214 | UINT8 num_sectors[2]; 215 | UINT8 media_type; 216 | UINT8 num_fat_sectors[2]; 217 | UINT8 sectors_in_track[2]; 218 | UINT8 num_heads[2]; 219 | UINT8 num_hid_sectors[4]; 220 | UINT8 num_huge_sectors[4]; 221 | UINT8 num_fat32_sectors[4]; 222 | UINT8 ext_flags[2]; 223 | UINT8 fs_version[2]; 224 | UINT8 root_cluster[4]; 225 | UINT8 fsinfo_sector[2]; 226 | UINT8 backup_sector[2]; 227 | UINT8 reserved[12]; 228 | 229 | UINT8 phy_drv_no; 230 | UINT8 ext_reserved; 231 | UINT8 ext_signature; 232 | UINT8 vol_serial[4]; 233 | UINT8 vol_label[11]; 234 | UINT8 vol_type[8]; 235 | } BPB32_T; 236 | 237 | typedef struct { 238 | UINT8 reserved1[53]; 239 | UINT8 vol_offset[8]; 240 | UINT8 vol_length[8]; 241 | UINT8 fat_offset[4]; 242 | UINT8 fat_length[4]; 243 | UINT8 clu_offset[4]; 244 | UINT8 clu_count[4]; 245 | UINT8 root_cluster[4]; 246 | UINT8 vol_serial[4]; 247 | UINT8 fs_version[2]; 248 | UINT8 vol_flags[2]; 249 | UINT8 sector_size_bits; 250 | UINT8 sectors_per_clu_bits; 251 | UINT8 num_fats; 252 | UINT8 phy_drv_no; 253 | UINT8 perc_in_use; 254 | UINT8 reserved2[7]; 255 | } BPBEX_T; 256 | 257 | typedef struct { 258 | UINT8 signature1[4]; 259 | UINT8 reserved1[480]; 260 | UINT8 signature2[4]; 261 | UINT8 free_cluster[4]; 262 | UINT8 next_cluster[4]; 263 | UINT8 reserved2[14]; 264 | UINT8 signature3[2]; 265 | } FSI_SECTOR_T; 266 | 267 | typedef struct { 268 | UINT8 dummy[32]; 269 | } DENTRY_T; 270 | 271 | typedef struct { 272 | UINT8 name[DOS_NAME_LENGTH]; 273 | UINT8 attr; 274 | UINT8 lcase; 275 | UINT8 create_time_ms; 276 | UINT8 create_time[2]; 277 | UINT8 create_date[2]; 278 | UINT8 access_date[2]; 279 | UINT8 start_clu_hi[2]; 280 | UINT8 modify_time[2]; 281 | UINT8 modify_date[2]; 282 | UINT8 start_clu_lo[2]; 283 | UINT8 size[4]; 284 | } DOS_DENTRY_T; 285 | 286 | typedef struct { 287 | UINT8 order; 288 | UINT8 unicode_0_4[10]; 289 | UINT8 attr; 290 | UINT8 sysid; 291 | UINT8 checksum; 292 | UINT8 unicode_5_10[12]; 293 | UINT8 start_clu[2]; 294 | UINT8 unicode_11_12[4]; 295 | } EXT_DENTRY_T; 296 | 297 | typedef struct { 298 | UINT8 type; 299 | UINT8 num_ext; 300 | UINT8 checksum[2]; 301 | UINT8 attr[2]; 302 | UINT8 reserved1[2]; 303 | UINT8 create_time[2]; 304 | UINT8 create_date[2]; 305 | UINT8 modify_time[2]; 306 | UINT8 modify_date[2]; 307 | UINT8 access_time[2]; 308 | UINT8 access_date[2]; 309 | UINT8 create_time_ms; 310 | UINT8 modify_time_ms; 311 | UINT8 access_time_ms; 312 | UINT8 reserved2[9]; 313 | } FILE_DENTRY_T; 314 | 315 | typedef struct { 316 | UINT8 type; 317 | UINT8 flags; 318 | UINT8 reserved1; 319 | UINT8 name_len; 320 | UINT8 name_hash[2]; 321 | UINT8 reserved2[2]; 322 | UINT8 valid_size[8]; 323 | UINT8 reserved3[4]; 324 | UINT8 start_clu[4]; 325 | UINT8 size[8]; 326 | } STRM_DENTRY_T; 327 | 328 | typedef struct { 329 | UINT8 type; 330 | UINT8 flags; 331 | UINT8 unicode_0_14[30]; 332 | } NAME_DENTRY_T; 333 | 334 | typedef struct { 335 | UINT8 type; 336 | UINT8 flags; 337 | UINT8 reserved[18]; 338 | UINT8 start_clu[4]; 339 | UINT8 size[8]; 340 | } BMAP_DENTRY_T; 341 | 342 | typedef struct { 343 | UINT8 type; 344 | UINT8 reserved1[3]; 345 | UINT8 checksum[4]; 346 | UINT8 reserved2[12]; 347 | UINT8 start_clu[4]; 348 | UINT8 size[8]; 349 | } CASE_DENTRY_T; 350 | 351 | typedef struct { 352 | UINT8 type; 353 | UINT8 label_len; 354 | UINT8 unicode_0_10[22]; 355 | UINT8 reserved[8]; 356 | } VOLM_DENTRY_T; 357 | 358 | typedef struct { 359 | UINT32 dir; 360 | INT32 entry; 361 | CHAIN_T clu; 362 | } UENTRY_T; 363 | 364 | typedef struct __FS_STRUCT_T { 365 | UINT32 mounted; 366 | struct super_block *sb; 367 | struct semaphore v_sem; 368 | } FS_STRUCT_T; 369 | 370 | typedef struct { 371 | INT32 (*alloc_cluster)(struct super_block *sb, INT32 num_alloc, CHAIN_T *p_chain); 372 | void (*free_cluster)(struct super_block *sb, CHAIN_T *p_chain, INT32 do_relse); 373 | INT32 (*count_used_clusters)(struct super_block *sb); 374 | 375 | INT32 (*init_dir_entry)(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT32 type, 376 | UINT32 start_clu, UINT64 size); 377 | INT32 (*init_ext_entry)(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, INT32 num_entries, 378 | UNI_NAME_T *p_uniname, DOS_NAME_T *p_dosname); 379 | INT32 (*find_dir_entry)(struct super_block *sb, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, INT32 num_entries, DOS_NAME_T *p_dosname, UINT32 type); 380 | void (*delete_dir_entry)(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, INT32 offset, INT32 num_entries); 381 | void (*get_uni_name_from_ext_entry)(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT16 *uniname); 382 | INT32 (*count_ext_entries)(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, DENTRY_T *p_entry); 383 | INT32 (*calc_num_entries)(UNI_NAME_T *p_uniname); 384 | 385 | UINT32 (*get_entry_type)(DENTRY_T *p_entry); 386 | void (*set_entry_type)(DENTRY_T *p_entry, UINT32 type); 387 | UINT32 (*get_entry_attr)(DENTRY_T *p_entry); 388 | void (*set_entry_attr)(DENTRY_T *p_entry, UINT32 attr); 389 | UINT8 (*get_entry_flag)(DENTRY_T *p_entry); 390 | void (*set_entry_flag)(DENTRY_T *p_entry, UINT8 flag); 391 | UINT32 (*get_entry_clu0)(DENTRY_T *p_entry); 392 | void (*set_entry_clu0)(DENTRY_T *p_entry, UINT32 clu0); 393 | UINT64 (*get_entry_size)(DENTRY_T *p_entry); 394 | void (*set_entry_size)(DENTRY_T *p_entry, UINT64 size); 395 | void (*get_entry_time)(DENTRY_T *p_entry, TIMESTAMP_T *tp, UINT8 mode); 396 | void (*set_entry_time)(DENTRY_T *p_entry, TIMESTAMP_T *tp, UINT8 mode); 397 | } FS_FUNC_T; 398 | 399 | typedef struct __FS_INFO_T { 400 | UINT32 drv; 401 | UINT32 vol_type; 402 | UINT32 vol_id; 403 | 404 | UINT64 num_sectors; 405 | UINT32 num_clusters; 406 | UINT32 cluster_size; 407 | UINT32 cluster_size_bits; 408 | UINT32 sectors_per_clu; 409 | UINT32 sectors_per_clu_bits; 410 | 411 | SECTOR PBR_sector; 412 | SECTOR FAT1_start_sector; 413 | SECTOR FAT2_start_sector; 414 | SECTOR root_start_sector; 415 | SECTOR data_start_sector; 416 | UINT64 num_FAT_sectors; 417 | 418 | UINT32 root_dir; 419 | UINT32 dentries_in_root; 420 | UINT32 dentries_per_clu; 421 | 422 | UINT32 vol_flag; 423 | struct buffer_head *pbr_bh; 424 | 425 | UINT32 map_clu; 426 | UINT32 map_sectors; 427 | struct buffer_head **vol_amap; 428 | 429 | UINT16 **vol_utbl; 430 | 431 | UINT32 clu_srch_ptr; 432 | UINT32 used_clusters; 433 | UENTRY_T hint_uentry; 434 | 435 | UINT32 dev_ejected; 436 | 437 | FS_FUNC_T *fs_func; 438 | 439 | BUF_CACHE_T FAT_cache_array[FAT_CACHE_SIZE]; 440 | BUF_CACHE_T FAT_cache_lru_list; 441 | BUF_CACHE_T FAT_cache_hash_list[FAT_CACHE_HASH_SIZE]; 442 | 443 | BUF_CACHE_T buf_cache_array[BUF_CACHE_SIZE]; 444 | BUF_CACHE_T buf_cache_lru_list; 445 | BUF_CACHE_T buf_cache_hash_list[BUF_CACHE_HASH_SIZE]; 446 | } FS_INFO_T; 447 | 448 | #define ES_2_ENTRIES 2 449 | #define ES_3_ENTRIES 3 450 | #define ES_ALL_ENTRIES 0 451 | 452 | typedef struct { 453 | SECTOR sector; 454 | INT32 offset; 455 | INT32 alloc_flag; 456 | UINT32 num_entries; 457 | 458 | void *__buf; 459 | } ENTRY_SET_CACHE_T; 460 | 461 | INT32 ffsInit(void); 462 | INT32 ffsShutdown(void); 463 | 464 | INT32 ffsMountVol(struct super_block *sb, INT32 drv); 465 | INT32 ffsUmountVol(struct super_block *sb); 466 | INT32 ffsCheckVol(struct super_block *sb); 467 | INT32 ffsGetVolInfo(struct super_block *sb, VOL_INFO_T *info); 468 | INT32 ffsSyncVol(struct super_block *sb, INT32 do_sync); 469 | 470 | INT32 ffsLookupFile(struct inode *inode, UINT8 *path, FILE_ID_T *fid); 471 | INT32 ffsCreateFile(struct inode *inode, UINT8 *path, UINT8 mode, FILE_ID_T *fid); 472 | INT32 ffsReadFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *rcount); 473 | INT32 ffsWriteFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *wcount); 474 | INT32 ffsTruncateFile(struct inode *inode, UINT64 old_size, UINT64 new_size); 475 | INT32 ffsMoveFile(struct inode *old_parent_inode, FILE_ID_T *fid, struct inode *new_parent_inode, struct dentry *new_dentry); 476 | INT32 ffsRemoveFile(struct inode *inode, FILE_ID_T *fid); 477 | INT32 ffsSetAttr(struct inode *inode, UINT32 attr); 478 | INT32 ffsGetStat(struct inode *inode, DIR_ENTRY_T *info); 479 | INT32 ffsSetStat(struct inode *inode, DIR_ENTRY_T *info); 480 | INT32 ffsMapCluster(struct inode *inode, INT32 clu_offset, UINT32 *clu); 481 | 482 | INT32 ffsCreateDir(struct inode *inode, UINT8 *path, FILE_ID_T *fid); 483 | INT32 ffsReadDir(struct inode *inode, DIR_ENTRY_T *dir_ent); 484 | INT32 ffsRemoveDir(struct inode *inode, FILE_ID_T *fid); 485 | INT32 ffsRemoveEntry(struct inode *inode, FILE_ID_T *fid); 486 | 487 | INT32 fs_init(void); 488 | INT32 fs_shutdown(void); 489 | void fs_set_vol_flags(struct super_block *sb, UINT32 new_flag); 490 | void fs_sync(struct super_block *sb, INT32 do_sync); 491 | void fs_error(struct super_block *sb); 492 | 493 | INT32 clear_cluster(struct super_block *sb, UINT32 clu); 494 | INT32 fat_alloc_cluster(struct super_block *sb, INT32 num_alloc, CHAIN_T *p_chain); 495 | INT32 exfat_alloc_cluster(struct super_block *sb, INT32 num_alloc, CHAIN_T *p_chain); 496 | void fat_free_cluster(struct super_block *sb, CHAIN_T *p_chain, INT32 do_relse); 497 | void exfat_free_cluster(struct super_block *sb, CHAIN_T *p_chain, INT32 do_relse); 498 | UINT32 find_last_cluster(struct super_block *sb, CHAIN_T *p_chain); 499 | INT32 count_num_clusters(struct super_block *sb, CHAIN_T *dir); 500 | INT32 fat_count_used_clusters(struct super_block *sb); 501 | INT32 exfat_count_used_clusters(struct super_block *sb); 502 | void exfat_chain_cont_cluster(struct super_block *sb, UINT32 chain, INT32 len); 503 | 504 | INT32 load_alloc_bitmap(struct super_block *sb); 505 | void free_alloc_bitmap(struct super_block *sb); 506 | INT32 set_alloc_bitmap(struct super_block *sb, UINT32 clu); 507 | INT32 clr_alloc_bitmap(struct super_block *sb, UINT32 clu); 508 | UINT32 test_alloc_bitmap(struct super_block *sb, UINT32 clu); 509 | void sync_alloc_bitmap(struct super_block *sb); 510 | 511 | INT32 load_upcase_table(struct super_block *sb); 512 | void free_upcase_table(struct super_block *sb); 513 | 514 | UINT32 fat_get_entry_type(DENTRY_T *p_entry); 515 | UINT32 exfat_get_entry_type(DENTRY_T *p_entry); 516 | void fat_set_entry_type(DENTRY_T *p_entry, UINT32 type); 517 | void exfat_set_entry_type(DENTRY_T *p_entry, UINT32 type); 518 | UINT32 fat_get_entry_attr(DENTRY_T *p_entry); 519 | UINT32 exfat_get_entry_attr(DENTRY_T *p_entry); 520 | void fat_set_entry_attr(DENTRY_T *p_entry, UINT32 attr); 521 | void exfat_set_entry_attr(DENTRY_T *p_entry, UINT32 attr); 522 | UINT8 fat_get_entry_flag(DENTRY_T *p_entry); 523 | UINT8 exfat_get_entry_flag(DENTRY_T *p_entry); 524 | void fat_set_entry_flag(DENTRY_T *p_entry, UINT8 flag); 525 | void exfat_set_entry_flag(DENTRY_T *p_entry, UINT8 flag); 526 | UINT32 fat_get_entry_clu0(DENTRY_T *p_entry); 527 | UINT32 exfat_get_entry_clu0(DENTRY_T *p_entry); 528 | void fat_set_entry_clu0(DENTRY_T *p_entry, UINT32 start_clu); 529 | void exfat_set_entry_clu0(DENTRY_T *p_entry, UINT32 start_clu); 530 | UINT64 fat_get_entry_size(DENTRY_T *p_entry); 531 | UINT64 exfat_get_entry_size(DENTRY_T *p_entry); 532 | void fat_set_entry_size(DENTRY_T *p_entry, UINT64 size); 533 | void exfat_set_entry_size(DENTRY_T *p_entry, UINT64 size); 534 | void fat_get_entry_time(DENTRY_T *p_entry, TIMESTAMP_T *tp, UINT8 mode); 535 | void exfat_get_entry_time(DENTRY_T *p_entry, TIMESTAMP_T *tp, UINT8 mode); 536 | void fat_set_entry_time(DENTRY_T *p_entry, TIMESTAMP_T *tp, UINT8 mode); 537 | void exfat_set_entry_time(DENTRY_T *p_entry, TIMESTAMP_T *tp, UINT8 mode); 538 | INT32 fat_init_dir_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT32 type, UINT32 start_clu, UINT64 size); 539 | INT32 exfat_init_dir_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT32 type, UINT32 start_clu, UINT64 size); 540 | INT32 fat_init_ext_dir_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, INT32 num_entries, UNI_NAME_T *p_uniname, DOS_NAME_T *p_dosname); 541 | INT32 exfat_init_ext_dir_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, INT32 num_entries, UNI_NAME_T *p_uniname, DOS_NAME_T *p_dosname); 542 | void init_dos_entry(DOS_DENTRY_T *ep, UINT32 type, UINT32 start_clu, UINT8 tz_utc); 543 | void init_ext_entry(EXT_DENTRY_T *ep, INT32 order, UINT8 chksum, UINT16 *uniname); 544 | void init_file_entry(FILE_DENTRY_T *ep, UINT32 type, UINT8 tz_utc); 545 | void init_strm_entry(STRM_DENTRY_T *ep, UINT8 flags, UINT32 start_clu, UINT64 size); 546 | void init_name_entry(NAME_DENTRY_T *ep, UINT16 *uniname); 547 | void fat_delete_dir_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, INT32 order, INT32 num_entries); 548 | void exfat_delete_dir_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, INT32 order, INT32 num_entries); 549 | 550 | INT32 find_location(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, SECTOR *sector, INT32 *offset); 551 | DENTRY_T *get_entry_with_sector(struct super_block *sb, SECTOR sector, INT32 offset); 552 | DENTRY_T *get_entry_in_dir(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, SECTOR *sector); 553 | ENTRY_SET_CACHE_T *get_entry_set_in_dir (struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT32 type, DENTRY_T **file_ep); 554 | void release_entry_set (ENTRY_SET_CACHE_T *es); 555 | INT32 write_whole_entry_set (struct super_block *sb, ENTRY_SET_CACHE_T *es); 556 | INT32 write_partial_entries_in_entry_set (struct super_block *sb, ENTRY_SET_CACHE_T *es, DENTRY_T *ep, UINT32 count); 557 | INT32 search_deleted_or_unused_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 num_entries); 558 | INT32 find_empty_entry(struct inode *inode, CHAIN_T *p_dir, INT32 num_entries); 559 | INT32 fat_find_dir_entry(struct super_block *sb, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, INT32 num_entries, DOS_NAME_T *p_dosname, UINT32 type); 560 | INT32 exfat_find_dir_entry(struct super_block *sb, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, INT32 num_entries, DOS_NAME_T *p_dosname, UINT32 type); 561 | INT32 fat_count_ext_entries(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, DENTRY_T *p_entry); 562 | INT32 exfat_count_ext_entries(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, DENTRY_T *p_entry); 563 | INT32 count_dos_name_entries(struct super_block *sb, CHAIN_T *p_dir, UINT32 type); 564 | void update_dir_checksum(struct super_block *sb, CHAIN_T *p_dir, INT32 entry); 565 | void update_dir_checksum_with_entry_set (struct super_block *sb, ENTRY_SET_CACHE_T *es); 566 | BOOL is_dir_empty(struct super_block *sb, CHAIN_T *p_dir); 567 | 568 | INT32 get_num_entries_and_dos_name(struct super_block *sb, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, INT32 *entries, DOS_NAME_T *p_dosname); 569 | void get_uni_name_from_dos_entry(struct super_block *sb, DOS_DENTRY_T *ep, UNI_NAME_T *p_uniname, UINT8 mode); 570 | void fat_get_uni_name_from_ext_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT16 *uniname); 571 | void exfat_get_uni_name_from_ext_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT16 *uniname); 572 | INT32 extract_uni_name_from_ext_entry(EXT_DENTRY_T *ep, UINT16 *uniname, INT32 order); 573 | INT32 extract_uni_name_from_name_entry(NAME_DENTRY_T *ep, UINT16 *uniname, INT32 order); 574 | INT32 fat_generate_dos_name(struct super_block *sb, CHAIN_T *p_dir, DOS_NAME_T *p_dosname); 575 | void fat_attach_count_to_dos_name(UINT8 *dosname, INT32 count); 576 | INT32 fat_calc_num_entries(UNI_NAME_T *p_uniname); 577 | INT32 exfat_calc_num_entries(UNI_NAME_T *p_uniname); 578 | UINT8 calc_checksum_1byte(void *data, INT32 len, UINT8 chksum); 579 | UINT16 calc_checksum_2byte(void *data, INT32 len, UINT16 chksum, INT32 type); 580 | UINT32 calc_checksum_4byte(void *data, INT32 len, UINT32 chksum, INT32 type); 581 | 582 | INT32 resolve_path(struct inode *inode, UINT8 *path, CHAIN_T *p_dir, UNI_NAME_T *p_uniname); 583 | INT32 resolve_name(UINT8 *name, UINT8 **arg); 584 | 585 | INT32 fat16_mount(struct super_block *sb, PBR_SECTOR_T *p_pbr); 586 | INT32 fat32_mount(struct super_block *sb, PBR_SECTOR_T *p_pbr); 587 | INT32 exfat_mount(struct super_block *sb, PBR_SECTOR_T *p_pbr); 588 | INT32 create_dir(struct inode *inode, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, FILE_ID_T *fid); 589 | INT32 create_file(struct inode *inode, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, UINT8 mode, FILE_ID_T *fid); 590 | void remove_file(struct inode *inode, CHAIN_T *p_dir, INT32 entry); 591 | INT32 rename_file(struct inode *inode, CHAIN_T *p_dir, INT32 old_entry, UNI_NAME_T *p_uniname, FILE_ID_T *fid); 592 | INT32 move_file(struct inode *inode, CHAIN_T *p_olddir, INT32 oldentry, CHAIN_T *p_newdir, UNI_NAME_T *p_uniname, FILE_ID_T *fid); 593 | 594 | INT32 sector_read(struct super_block *sb, SECTOR sec, struct buffer_head **bh, INT32 read); 595 | INT32 sector_write(struct super_block *sb, SECTOR sec, struct buffer_head *bh, INT32 sync); 596 | INT32 multi_sector_read(struct super_block *sb, SECTOR sec, struct buffer_head **bh, UINT32 num_secs, INT32 read); 597 | INT32 multi_sector_write(struct super_block *sb, SECTOR sec, struct buffer_head *bh, UINT32 num_secs, INT32 sync); 598 | 599 | #ifdef __cplusplus 600 | } 601 | #endif 602 | 603 | #endif 604 | -------------------------------------------------------------------------------- /exfat_api.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation; either version 2 7 | * of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | #include "exfat_global.h" 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "exfat_data.h" 26 | #include "exfat_oal.h" 27 | 28 | #include "exfat_part.h" 29 | #include "exfat_nls.h" 30 | #include "exfat_api.h" 31 | #include "exfat_super.h" 32 | #include "exfat.h" 33 | 34 | extern FS_STRUCT_T fs_struct[]; 35 | 36 | extern struct semaphore z_sem; 37 | 38 | INT32 FsInit(void) 39 | { 40 | INT32 i; 41 | 42 | for (i = 0; i < MAX_DRIVE; i++) { 43 | fs_struct[i].mounted = FALSE; 44 | fs_struct[i].sb = NULL; 45 | sm_init(&(fs_struct[i].v_sem)); 46 | } 47 | 48 | return(ffsInit()); 49 | } 50 | 51 | INT32 FsShutdown(void) 52 | { 53 | INT32 i; 54 | 55 | for (i = 0; i < MAX_DRIVE; i++) { 56 | if (!fs_struct[i].mounted) continue; 57 | 58 | ffsUmountVol(fs_struct[i].sb); 59 | } 60 | 61 | return(ffsShutdown()); 62 | } 63 | 64 | INT32 FsMountVol(struct super_block *sb) 65 | { 66 | INT32 err, drv; 67 | 68 | sm_P(&z_sem); 69 | 70 | for (drv = 0; drv < MAX_DRIVE; drv++) { 71 | if (!fs_struct[drv].mounted) break; 72 | } 73 | 74 | if (drv >= MAX_DRIVE) { 75 | err = FFS_ERROR; 76 | goto ret_unlock; 77 | } 78 | 79 | sm_P(&(fs_struct[drv].v_sem)); 80 | 81 | err = buf_init(sb); 82 | if (!err) { 83 | err = ffsMountVol(sb, drv); 84 | } 85 | 86 | sm_V(&(fs_struct[drv].v_sem)); 87 | 88 | if (!err) { 89 | fs_struct[drv].mounted = TRUE; 90 | fs_struct[drv].sb = sb; 91 | } else { 92 | buf_shutdown(sb); 93 | } 94 | ret_unlock: 95 | sm_V(&z_sem); 96 | 97 | return(err); 98 | } 99 | 100 | INT32 FsUmountVol(struct super_block *sb) 101 | { 102 | INT32 err; 103 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 104 | 105 | sm_P(&z_sem); 106 | 107 | sm_P(&(fs_struct[p_fs->drv].v_sem)); 108 | 109 | err = ffsUmountVol(sb); 110 | buf_shutdown(sb); 111 | 112 | sm_V(&(fs_struct[p_fs->drv].v_sem)); 113 | 114 | fs_struct[p_fs->drv].mounted = FALSE; 115 | fs_struct[p_fs->drv].sb = NULL; 116 | 117 | sm_V(&z_sem); 118 | 119 | return(err); 120 | } 121 | 122 | INT32 FsGetVolInfo(struct super_block *sb, VOL_INFO_T *info) 123 | { 124 | INT32 err; 125 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 126 | 127 | if (info == NULL) return(FFS_ERROR); 128 | 129 | sm_P(&(fs_struct[p_fs->drv].v_sem)); 130 | 131 | err = ffsGetVolInfo(sb, info); 132 | 133 | sm_V(&(fs_struct[p_fs->drv].v_sem)); 134 | 135 | return(err); 136 | } 137 | 138 | INT32 FsSyncVol(struct super_block *sb, INT32 do_sync) 139 | { 140 | INT32 err; 141 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 142 | 143 | sm_P(&(fs_struct[p_fs->drv].v_sem)); 144 | 145 | err = ffsSyncVol(sb, do_sync); 146 | 147 | sm_V(&(fs_struct[p_fs->drv].v_sem)); 148 | 149 | return(err); 150 | } 151 | 152 | INT32 FsLookupFile(struct inode *inode, UINT8 *path, FILE_ID_T *fid) 153 | { 154 | INT32 err; 155 | struct super_block *sb = inode->i_sb; 156 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 157 | 158 | if ((fid == NULL) || (path == NULL) || (STRLEN(path) == 0)) 159 | return(FFS_ERROR); 160 | 161 | sm_P(&(fs_struct[p_fs->drv].v_sem)); 162 | 163 | err = ffsLookupFile(inode, path, fid); 164 | 165 | sm_V(&(fs_struct[p_fs->drv].v_sem)); 166 | 167 | return(err); 168 | } 169 | 170 | INT32 FsCreateFile(struct inode *inode, UINT8 *path, UINT8 mode, FILE_ID_T *fid) 171 | { 172 | INT32 err; 173 | struct super_block *sb = inode->i_sb; 174 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 175 | 176 | if ((fid == NULL) || (path == NULL) || (STRLEN(path) == 0)) 177 | return(FFS_ERROR); 178 | 179 | sm_P(&(fs_struct[p_fs->drv].v_sem)); 180 | 181 | err = ffsCreateFile(inode, path, mode, fid); 182 | 183 | sm_V(&(fs_struct[p_fs->drv].v_sem)); 184 | 185 | return(err); 186 | } 187 | 188 | INT32 FsReadFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *rcount) 189 | { 190 | INT32 err; 191 | struct super_block *sb = inode->i_sb; 192 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 193 | 194 | if (fid == NULL) return(FFS_INVALIDFID); 195 | 196 | if (buffer == NULL) return(FFS_ERROR); 197 | 198 | sm_P(&(fs_struct[p_fs->drv].v_sem)); 199 | 200 | err = ffsReadFile(inode, fid, buffer, count, rcount); 201 | 202 | sm_V(&(fs_struct[p_fs->drv].v_sem)); 203 | 204 | return(err); 205 | } 206 | 207 | INT32 FsWriteFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *wcount) 208 | { 209 | INT32 err; 210 | struct super_block *sb = inode->i_sb; 211 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 212 | 213 | if (fid == NULL) return(FFS_INVALIDFID); 214 | 215 | if (buffer == NULL) return(FFS_ERROR); 216 | 217 | sm_P(&(fs_struct[p_fs->drv].v_sem)); 218 | 219 | err = ffsWriteFile(inode, fid, buffer, count, wcount); 220 | 221 | sm_V(&(fs_struct[p_fs->drv].v_sem)); 222 | 223 | return(err); 224 | } 225 | 226 | INT32 FsTruncateFile(struct inode *inode, UINT64 old_size, UINT64 new_size) 227 | { 228 | INT32 err; 229 | struct super_block *sb = inode->i_sb; 230 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 231 | 232 | sm_P(&(fs_struct[p_fs->drv].v_sem)); 233 | 234 | LOGD("entered (inode %p size %llu)\n", inode, new_size); 235 | 236 | err = ffsTruncateFile(inode, old_size, new_size); 237 | 238 | LOGD("exited (%d)\n", err); 239 | 240 | sm_V(&(fs_struct[p_fs->drv].v_sem)); 241 | 242 | return(err); 243 | } 244 | 245 | INT32 FsMoveFile(struct inode *old_parent_inode, FILE_ID_T *fid, struct inode *new_parent_inode, struct dentry *new_dentry) 246 | { 247 | INT32 err; 248 | struct super_block *sb = old_parent_inode->i_sb; 249 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 250 | 251 | if (fid == NULL) return(FFS_INVALIDFID); 252 | 253 | sm_P(&(fs_struct[p_fs->drv].v_sem)); 254 | 255 | err = ffsMoveFile(old_parent_inode, fid, new_parent_inode, new_dentry); 256 | 257 | sm_V(&(fs_struct[p_fs->drv].v_sem)); 258 | 259 | return(err); 260 | } 261 | 262 | INT32 FsRemoveFile(struct inode *inode, FILE_ID_T *fid) 263 | { 264 | INT32 err; 265 | struct super_block *sb = inode->i_sb; 266 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 267 | 268 | if (fid == NULL) return(FFS_INVALIDFID); 269 | 270 | sm_P(&(fs_struct[p_fs->drv].v_sem)); 271 | 272 | err = ffsRemoveFile(inode, fid); 273 | 274 | sm_V(&(fs_struct[p_fs->drv].v_sem)); 275 | 276 | return(err); 277 | } 278 | 279 | INT32 FsSetAttr(struct inode *inode, UINT32 attr) 280 | { 281 | INT32 err; 282 | struct super_block *sb = inode->i_sb; 283 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 284 | 285 | sm_P(&(fs_struct[p_fs->drv].v_sem)); 286 | 287 | err = ffsSetAttr(inode, attr); 288 | 289 | sm_V(&(fs_struct[p_fs->drv].v_sem)); 290 | 291 | return(err); 292 | } 293 | 294 | INT32 FsReadStat(struct inode *inode, DIR_ENTRY_T *info) 295 | { 296 | INT32 err; 297 | struct super_block *sb = inode->i_sb; 298 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 299 | 300 | sm_P(&(fs_struct[p_fs->drv].v_sem)); 301 | 302 | err = ffsGetStat(inode, info); 303 | 304 | sm_V(&(fs_struct[p_fs->drv].v_sem)); 305 | 306 | return(err); 307 | } 308 | 309 | INT32 FsWriteStat(struct inode *inode, DIR_ENTRY_T *info) 310 | { 311 | INT32 err; 312 | struct super_block *sb = inode->i_sb; 313 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 314 | 315 | sm_P(&(fs_struct[p_fs->drv].v_sem)); 316 | 317 | LOGD("entered (inode %p info %p\n", inode, info); 318 | 319 | err = ffsSetStat(inode, info); 320 | 321 | sm_V(&(fs_struct[p_fs->drv].v_sem)); 322 | 323 | LOGD("exited (%d)\n", err); 324 | 325 | return(err); 326 | } 327 | 328 | INT32 FsMapCluster(struct inode *inode, INT32 clu_offset, UINT32 *clu) 329 | { 330 | INT32 err; 331 | struct super_block *sb = inode->i_sb; 332 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 333 | 334 | if (clu == NULL) return(FFS_ERROR); 335 | 336 | sm_P(&(fs_struct[p_fs->drv].v_sem)); 337 | 338 | err = ffsMapCluster(inode, clu_offset, clu); 339 | 340 | sm_V(&(fs_struct[p_fs->drv].v_sem)); 341 | 342 | return(err); 343 | } 344 | 345 | INT32 FsCreateDir(struct inode *inode, UINT8 *path, FILE_ID_T *fid) 346 | { 347 | INT32 err; 348 | struct super_block *sb = inode->i_sb; 349 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 350 | 351 | if ((fid == NULL) || (path == NULL) || (STRLEN(path) == 0)) 352 | return(FFS_ERROR); 353 | 354 | sm_P(&(fs_struct[p_fs->drv].v_sem)); 355 | 356 | err = ffsCreateDir(inode, path, fid); 357 | 358 | sm_V(&(fs_struct[p_fs->drv].v_sem)); 359 | 360 | return(err); 361 | } 362 | 363 | INT32 FsReadDir(struct inode *inode, DIR_ENTRY_T *dir_entry) 364 | { 365 | INT32 err; 366 | struct super_block *sb = inode->i_sb; 367 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 368 | 369 | if (dir_entry == NULL) return(FFS_ERROR); 370 | 371 | sm_P(&(fs_struct[p_fs->drv].v_sem)); 372 | 373 | err = ffsReadDir(inode, dir_entry); 374 | 375 | sm_V(&(fs_struct[p_fs->drv].v_sem)); 376 | 377 | return(err); 378 | } 379 | 380 | INT32 FsRemoveDir(struct inode *inode, FILE_ID_T *fid) 381 | { 382 | INT32 err; 383 | struct super_block *sb = inode->i_sb; 384 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 385 | 386 | if (fid == NULL) return(FFS_INVALIDFID); 387 | 388 | sm_P(&(fs_struct[p_fs->drv].v_sem)); 389 | 390 | err = ffsRemoveDir(inode, fid); 391 | 392 | sm_V(&(fs_struct[p_fs->drv].v_sem)); 393 | 394 | return(err); 395 | } 396 | 397 | INT32 FsRemoveEntry(struct inode *inode, FILE_ID_T *fid) 398 | { 399 | INT32 err; 400 | struct super_block *sb = inode->i_sb; 401 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 402 | 403 | if (fid == NULL) return(FFS_INVALIDFID); 404 | 405 | sm_P(&(fs_struct[p_fs->drv].v_sem)); 406 | 407 | err = ffsRemoveEntry(inode, fid); 408 | 409 | sm_V(&(fs_struct[p_fs->drv].v_sem)); 410 | 411 | return(err); 412 | } 413 | 414 | EXPORT_SYMBOL(FsMountVol); 415 | EXPORT_SYMBOL(FsUmountVol); 416 | EXPORT_SYMBOL(FsGetVolInfo); 417 | EXPORT_SYMBOL(FsSyncVol); 418 | EXPORT_SYMBOL(FsLookupFile); 419 | EXPORT_SYMBOL(FsCreateFile); 420 | EXPORT_SYMBOL(FsReadFile); 421 | EXPORT_SYMBOL(FsWriteFile); 422 | EXPORT_SYMBOL(FsTruncateFile); 423 | EXPORT_SYMBOL(FsMoveFile); 424 | EXPORT_SYMBOL(FsRemoveFile); 425 | EXPORT_SYMBOL(FsSetAttr); 426 | EXPORT_SYMBOL(FsReadStat); 427 | EXPORT_SYMBOL(FsWriteStat); 428 | EXPORT_SYMBOL(FsMapCluster); 429 | EXPORT_SYMBOL(FsCreateDir); 430 | EXPORT_SYMBOL(FsReadDir); 431 | EXPORT_SYMBOL(FsRemoveDir); 432 | EXPORT_SYMBOL(FsRemoveEntry); 433 | 434 | #ifdef CONFIG_EXFAT_DEBUG 435 | INT32 FsReleaseCache(struct super_block *sb) 436 | { 437 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 438 | 439 | sm_P(&(fs_struct[p_fs->drv].v_sem)); 440 | 441 | FAT_release_all(sb); 442 | buf_release_all(sb); 443 | 444 | sm_V(&(fs_struct[p_fs->drv].v_sem)); 445 | 446 | return 0; 447 | } 448 | 449 | EXPORT_SYMBOL(FsReleaseCache); 450 | #endif 451 | -------------------------------------------------------------------------------- /exfat_api.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation; either version 2 7 | * of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | #ifndef _EXFAT_API_H 20 | #define _EXFAT_API_H 21 | 22 | #include "exfat_global.h" 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | #define EXFAT_SUPER_MAGIC (0x2011BAB0L) 29 | #define EXFAT_ROOT_INO 1 30 | 31 | #define FAT12 0x01 32 | #define FAT16 0x0E 33 | #define FAT32 0x0C 34 | #define EXFAT 0x07 35 | 36 | #define MAX_CHARSET_SIZE 3 37 | #define MAX_PATH_DEPTH 15 38 | #define MAX_NAME_LENGTH 256 39 | #define MAX_PATH_LENGTH 260 40 | #define DOS_NAME_LENGTH 11 41 | #define DOS_PATH_LENGTH 80 42 | 43 | #define ATTR_NORMAL 0x0000 44 | #define ATTR_READONLY 0x0001 45 | #define ATTR_HIDDEN 0x0002 46 | #define ATTR_SYSTEM 0x0004 47 | #define ATTR_VOLUME 0x0008 48 | #define ATTR_SUBDIR 0x0010 49 | #define ATTR_ARCHIVE 0x0020 50 | #define ATTR_SYMLINK 0x0040 51 | #define ATTR_EXTEND 0x000F 52 | #define ATTR_RWMASK 0x007E 53 | 54 | #define FM_REGULAR 0x00 55 | #define FM_SYMLINK 0x40 56 | 57 | #define FFS_SUCCESS 0 58 | #define FFS_MEDIAERR 1 59 | #define FFS_FORMATERR 2 60 | #define FFS_MOUNTED 3 61 | #define FFS_NOTMOUNTED 4 62 | #define FFS_ALIGNMENTERR 5 63 | #define FFS_SEMAPHOREERR 6 64 | #define FFS_INVALIDPATH 7 65 | #define FFS_INVALIDFID 8 66 | #define FFS_NOTFOUND 9 67 | #define FFS_FILEEXIST 10 68 | #define FFS_PERMISSIONERR 11 69 | #define FFS_NOTOPENED 12 70 | #define FFS_MAXOPENED 13 71 | #define FFS_FULL 14 72 | #define FFS_EOF 15 73 | #define FFS_DIRBUSY 16 74 | #define FFS_MEMORYERR 17 75 | #define FFS_NAMETOOLONG 18 76 | #define FFS_ERROR 19 77 | 78 | typedef struct { 79 | UINT16 Year; 80 | UINT16 Month; 81 | UINT16 Day; 82 | UINT16 Hour; 83 | UINT16 Minute; 84 | UINT16 Second; 85 | UINT16 MilliSecond; 86 | } DATE_TIME_T; 87 | 88 | typedef struct { 89 | UINT32 Offset; 90 | UINT32 Size; 91 | } PART_INFO_T; 92 | 93 | typedef struct { 94 | UINT32 SecSize; 95 | UINT32 DevSize; 96 | } DEV_INFO_T; 97 | 98 | typedef struct { 99 | UINT32 FatType; 100 | UINT32 ClusterSize; 101 | UINT32 NumClusters; 102 | UINT32 FreeClusters; 103 | UINT32 UsedClusters; 104 | } VOL_INFO_T; 105 | 106 | typedef struct { 107 | UINT32 dir; 108 | INT32 size; 109 | UINT8 flags; 110 | } CHAIN_T; 111 | 112 | typedef struct { 113 | CHAIN_T dir; 114 | INT32 entry; 115 | UINT32 type; 116 | UINT32 attr; 117 | UINT32 start_clu; 118 | UINT64 size; 119 | UINT8 flags; 120 | INT64 rwoffset; 121 | INT32 hint_last_off; 122 | UINT32 hint_last_clu; 123 | } FILE_ID_T; 124 | 125 | typedef struct { 126 | INT8 Name[MAX_NAME_LENGTH *MAX_CHARSET_SIZE]; 127 | INT8 ShortName[DOS_NAME_LENGTH + 2]; 128 | UINT32 Attr; 129 | UINT64 Size; 130 | UINT32 NumSubdirs; 131 | DATE_TIME_T CreateTimestamp; 132 | DATE_TIME_T ModifyTimestamp; 133 | DATE_TIME_T AccessTimestamp; 134 | } DIR_ENTRY_T; 135 | 136 | INT32 FsInit(void); 137 | INT32 FsShutdown(void); 138 | 139 | INT32 FsMountVol(struct super_block *sb); 140 | INT32 FsUmountVol(struct super_block *sb); 141 | INT32 FsGetVolInfo(struct super_block *sb, VOL_INFO_T *info); 142 | INT32 FsSyncVol(struct super_block *sb, INT32 do_sync); 143 | 144 | INT32 FsLookupFile(struct inode *inode, UINT8 *path, FILE_ID_T *fid); 145 | INT32 FsCreateFile(struct inode *inode, UINT8 *path, UINT8 mode, FILE_ID_T *fid); 146 | INT32 FsReadFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *rcount); 147 | INT32 FsWriteFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *wcount); 148 | INT32 FsTruncateFile(struct inode *inode, UINT64 old_size, UINT64 new_size); 149 | INT32 FsMoveFile(struct inode *old_parent_inode, FILE_ID_T *fid, struct inode *new_parent_inode, struct dentry *new_dentry); 150 | INT32 FsRemoveFile(struct inode *inode, FILE_ID_T *fid); 151 | INT32 FsSetAttr(struct inode *inode, UINT32 attr); 152 | INT32 FsReadStat(struct inode *inode, DIR_ENTRY_T *info); 153 | INT32 FsWriteStat(struct inode *inode, DIR_ENTRY_T *info); 154 | INT32 FsMapCluster(struct inode *inode, INT32 clu_offset, UINT32 *clu); 155 | 156 | INT32 FsCreateDir(struct inode *inode, UINT8 *path, FILE_ID_T *fid); 157 | INT32 FsReadDir(struct inode *inode, DIR_ENTRY_T *dir_entry); 158 | INT32 FsRemoveDir(struct inode *inode, FILE_ID_T *fid); 159 | INT32 FsRemoveEntry(struct inode *inode, FILE_ID_T *fid); 160 | 161 | INT32 FsReleaseCache(struct super_block *sb); 162 | #ifdef __cplusplus 163 | } 164 | #endif 165 | #endif 166 | -------------------------------------------------------------------------------- /exfat_blkdev.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation; either version 2 7 | * of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | #include "exfat_global.h" 20 | 21 | #include 22 | 23 | #include "exfat_blkdev.h" 24 | #include "exfat_data.h" 25 | #include "exfat_api.h" 26 | #include "exfat_super.h" 27 | 28 | INT32 bdev_init(void) 29 | { 30 | return(FFS_SUCCESS); 31 | } 32 | 33 | INT32 bdev_shutdown(void) 34 | { 35 | return(FFS_SUCCESS); 36 | } 37 | 38 | INT32 bdev_open(struct super_block *sb) 39 | { 40 | BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); 41 | 42 | if (p_bd->opened) return(FFS_SUCCESS); 43 | 44 | p_bd->sector_size = bdev_logical_block_size(sb->s_bdev); 45 | p_bd->sector_size_bits = my_log2(p_bd->sector_size); 46 | p_bd->sector_size_mask = p_bd->sector_size - 1; 47 | p_bd->num_sectors = i_size_read(sb->s_bdev->bd_inode) >> p_bd->sector_size_bits; 48 | 49 | p_bd->opened = TRUE; 50 | 51 | return(FFS_SUCCESS); 52 | } 53 | 54 | INT32 bdev_close(struct super_block *sb) 55 | { 56 | BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); 57 | 58 | if (!p_bd->opened) return(FFS_SUCCESS); 59 | 60 | p_bd->opened = FALSE; 61 | return(FFS_SUCCESS); 62 | } 63 | 64 | INT32 bdev_read(struct super_block *sb, SECTOR secno, struct buffer_head **bh, UINT32 num_secs, INT32 read) 65 | { 66 | BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); 67 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 68 | #ifdef CONFIG_EXFAT_DEBUG 69 | struct exfat_sb_info *sbi = EXFAT_SB(sb); 70 | long flags = sbi->debug_flags; 71 | 72 | if (flags & EXFAT_DEBUGFLAGS_ERROR_RW) return (FFS_MEDIAERR); 73 | #endif 74 | 75 | if (!p_bd->opened) return(FFS_MEDIAERR); 76 | 77 | if (*bh) __brelse(*bh); 78 | 79 | if (read) 80 | *bh = __bread(sb->s_bdev, secno, num_secs << p_bd->sector_size_bits); 81 | else 82 | *bh = __getblk(sb->s_bdev, secno, num_secs << p_bd->sector_size_bits); 83 | 84 | if (*bh) return(FFS_SUCCESS); 85 | 86 | WARN(!p_fs->dev_ejected, 87 | "[EXFAT] No bh, device seems wrong or to be ejected.\n"); 88 | 89 | return(FFS_MEDIAERR); 90 | } 91 | 92 | INT32 bdev_write(struct super_block *sb, SECTOR secno, struct buffer_head *bh, UINT32 num_secs, INT32 sync) 93 | { 94 | INT32 count; 95 | struct buffer_head *bh2; 96 | BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); 97 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 98 | #ifdef CONFIG_EXFAT_DEBUG 99 | struct exfat_sb_info *sbi = EXFAT_SB(sb); 100 | long flags = sbi->debug_flags; 101 | 102 | if (flags & EXFAT_DEBUGFLAGS_ERROR_RW) return (FFS_MEDIAERR); 103 | #endif 104 | 105 | if (!p_bd->opened) return(FFS_MEDIAERR); 106 | 107 | if (secno == bh->b_blocknr) { 108 | set_buffer_uptodate(bh); 109 | mark_buffer_dirty(bh); 110 | 111 | if (sync && (sync_dirty_buffer(bh) != 0)) 112 | return (FFS_MEDIAERR); 113 | } else { 114 | count = num_secs << p_bd->sector_size_bits; 115 | 116 | bh2 = __getblk(sb->s_bdev, secno, count); 117 | 118 | if (bh2 == NULL) 119 | goto no_bh; 120 | 121 | lock_buffer(bh2); 122 | MEMCPY(bh2->b_data, bh->b_data, count); 123 | set_buffer_uptodate(bh2); 124 | mark_buffer_dirty(bh2); 125 | unlock_buffer(bh2); 126 | if (sync && (sync_dirty_buffer(bh2) != 0)) { 127 | __brelse(bh2); 128 | goto no_bh; 129 | } 130 | __brelse(bh2); 131 | } 132 | 133 | return(FFS_SUCCESS); 134 | 135 | no_bh: 136 | WARN(!p_fs->dev_ejected, 137 | "[EXFAT] No bh, device seems wrong or to be ejected.\n"); 138 | 139 | return (FFS_MEDIAERR); 140 | } 141 | 142 | INT32 bdev_sync(struct super_block *sb) 143 | { 144 | BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); 145 | #ifdef CONFIG_EXFAT_DEBUG 146 | struct exfat_sb_info *sbi = EXFAT_SB(sb); 147 | long flags = sbi->debug_flags; 148 | 149 | if (flags & EXFAT_DEBUGFLAGS_ERROR_RW) return (FFS_MEDIAERR); 150 | #endif 151 | 152 | if (!p_bd->opened) return(FFS_MEDIAERR); 153 | 154 | return sync_blockdev(sb->s_bdev); 155 | } 156 | 157 | INT32 bdev_reada(struct super_block *sb, SECTOR secno, UINT32 num_secs) 158 | { 159 | BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); 160 | UINT32 sects_per_page = (PAGE_SIZE >> sb->s_blocksize_bits); 161 | struct blk_plug plug; 162 | UINT32 i; 163 | 164 | if (!p_bd->opened) 165 | return (FFS_MEDIAERR); 166 | 167 | blk_start_plug(&plug); 168 | for (i = 0; i < num_secs; i++) { 169 | if (i && !(i & (sects_per_page - 1))) 170 | blk_flush_plug_list(&plug, false); 171 | sb_breadahead(sb, secno + i); 172 | } 173 | blk_finish_plug(&plug); 174 | 175 | return 0; 176 | } 177 | -------------------------------------------------------------------------------- /exfat_blkdev.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation; either version 2 7 | * of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | #ifndef _EXFAT_BLKDEV_H 20 | #define _EXFAT_BLKDEV_H 21 | 22 | #include "exfat_global.h" 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | typedef struct __BD_INFO_T { 28 | INT32 sector_size; 29 | INT32 sector_size_bits; 30 | INT32 sector_size_mask; 31 | UINT64 num_sectors; 32 | BOOL opened; 33 | } BD_INFO_T; 34 | 35 | INT32 bdev_init(void); 36 | INT32 bdev_shutdown(void); 37 | INT32 bdev_open(struct super_block *sb); 38 | INT32 bdev_close(struct super_block *sb); 39 | INT32 bdev_read(struct super_block *sb, SECTOR secno, struct buffer_head **bh, UINT32 num_secs, INT32 read); 40 | INT32 bdev_write(struct super_block *sb, SECTOR secno, struct buffer_head *bh, UINT32 num_secs, INT32 sync); 41 | INT32 bdev_sync(struct super_block *sb); 42 | INT32 bdev_reada(struct super_block *sb, SECTOR secno, UINT32 num_secs); 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | #endif 47 | -------------------------------------------------------------------------------- /exfat_cache.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation; either version 2 7 | * of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | #include "exfat.h" 20 | 21 | #include "exfat_cache.h" 22 | #include "exfat_super.h" 23 | 24 | extern FS_STRUCT_T fs_struct[]; 25 | 26 | #define sm_P(s) 27 | #define sm_V(s) 28 | 29 | static INT32 __FAT_read(struct super_block *sb, UINT32 loc, UINT32 *content); 30 | static INT32 __FAT_write(struct super_block *sb, UINT32 loc, UINT32 content); 31 | 32 | static BUF_CACHE_T *FAT_cache_find(struct super_block *sb, SECTOR sec); 33 | static BUF_CACHE_T *FAT_cache_get(struct super_block *sb, SECTOR sec); 34 | static void FAT_cache_insert_hash(struct super_block *sb, BUF_CACHE_T *bp); 35 | static void FAT_cache_remove_hash(BUF_CACHE_T *bp); 36 | 37 | static UINT8 *__buf_getblk(struct super_block *sb, SECTOR sec); 38 | 39 | static BUF_CACHE_T *buf_cache_find(struct super_block *sb, SECTOR sec); 40 | static BUF_CACHE_T *buf_cache_get(struct super_block *sb, SECTOR sec); 41 | static void buf_cache_insert_hash(struct super_block *sb, BUF_CACHE_T *bp); 42 | static void buf_cache_remove_hash(BUF_CACHE_T *bp); 43 | 44 | static void push_to_mru(BUF_CACHE_T *bp, BUF_CACHE_T *list); 45 | static void push_to_lru(BUF_CACHE_T *bp, BUF_CACHE_T *list); 46 | static void move_to_mru(BUF_CACHE_T *bp, BUF_CACHE_T *list); 47 | static void move_to_lru(BUF_CACHE_T *bp, BUF_CACHE_T *list); 48 | 49 | INT32 buf_init(struct super_block *sb) 50 | { 51 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 52 | 53 | INT32 i; 54 | 55 | p_fs->FAT_cache_lru_list.next = p_fs->FAT_cache_lru_list.prev = &p_fs->FAT_cache_lru_list; 56 | 57 | for (i = 0; i < FAT_CACHE_SIZE; i++) { 58 | p_fs->FAT_cache_array[i].drv = -1; 59 | p_fs->FAT_cache_array[i].sec = ~0; 60 | p_fs->FAT_cache_array[i].flag = 0; 61 | p_fs->FAT_cache_array[i].buf_bh = NULL; 62 | p_fs->FAT_cache_array[i].prev = p_fs->FAT_cache_array[i].next = NULL; 63 | push_to_mru(&(p_fs->FAT_cache_array[i]), &p_fs->FAT_cache_lru_list); 64 | } 65 | 66 | p_fs->buf_cache_lru_list.next = p_fs->buf_cache_lru_list.prev = &p_fs->buf_cache_lru_list; 67 | 68 | for (i = 0; i < BUF_CACHE_SIZE; i++) { 69 | p_fs->buf_cache_array[i].drv = -1; 70 | p_fs->buf_cache_array[i].sec = ~0; 71 | p_fs->buf_cache_array[i].flag = 0; 72 | p_fs->buf_cache_array[i].buf_bh = NULL; 73 | p_fs->buf_cache_array[i].prev = p_fs->buf_cache_array[i].next = NULL; 74 | push_to_mru(&(p_fs->buf_cache_array[i]), &p_fs->buf_cache_lru_list); 75 | } 76 | 77 | for (i = 0; i < FAT_CACHE_HASH_SIZE; i++) { 78 | p_fs->FAT_cache_hash_list[i].drv = -1; 79 | p_fs->FAT_cache_hash_list[i].sec = ~0; 80 | p_fs->FAT_cache_hash_list[i].hash_next = p_fs->FAT_cache_hash_list[i].hash_prev = &(p_fs->FAT_cache_hash_list[i]); 81 | } 82 | 83 | for (i = 0; i < FAT_CACHE_SIZE; i++) { 84 | FAT_cache_insert_hash(sb, &(p_fs->FAT_cache_array[i])); 85 | } 86 | 87 | for (i = 0; i < BUF_CACHE_HASH_SIZE; i++) { 88 | p_fs->buf_cache_hash_list[i].drv = -1; 89 | p_fs->buf_cache_hash_list[i].sec = ~0; 90 | p_fs->buf_cache_hash_list[i].hash_next = p_fs->buf_cache_hash_list[i].hash_prev = &(p_fs->buf_cache_hash_list[i]); 91 | } 92 | 93 | for (i = 0; i < BUF_CACHE_SIZE; i++) { 94 | buf_cache_insert_hash(sb, &(p_fs->buf_cache_array[i])); 95 | } 96 | 97 | return(FFS_SUCCESS); 98 | } 99 | 100 | INT32 buf_shutdown(struct super_block *sb) 101 | { 102 | return(FFS_SUCCESS); 103 | } 104 | 105 | INT32 FAT_read(struct super_block *sb, UINT32 loc, UINT32 *content) 106 | { 107 | INT32 ret; 108 | 109 | sm_P(&f_sem); 110 | 111 | ret = __FAT_read(sb, loc, content); 112 | 113 | sm_V(&f_sem); 114 | 115 | return(ret); 116 | } 117 | 118 | INT32 FAT_write(struct super_block *sb, UINT32 loc, UINT32 content) 119 | { 120 | INT32 ret; 121 | 122 | sm_P(&f_sem); 123 | 124 | ret = __FAT_write(sb, loc, content); 125 | 126 | sm_V(&f_sem); 127 | 128 | return(ret); 129 | } 130 | 131 | static INT32 __FAT_read(struct super_block *sb, UINT32 loc, UINT32 *content) 132 | { 133 | INT32 off; 134 | UINT32 _content; 135 | SECTOR sec; 136 | UINT8 *fat_sector, *fat_entry; 137 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 138 | BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); 139 | 140 | if (p_fs->vol_type == FAT12) { 141 | sec = p_fs->FAT1_start_sector + ((loc + (loc >> 1)) >> p_bd->sector_size_bits); 142 | off = (loc + (loc >> 1)) & p_bd->sector_size_mask; 143 | 144 | if (off == (p_bd->sector_size-1)) { 145 | fat_sector = FAT_getblk(sb, sec); 146 | if (!fat_sector) 147 | return -1; 148 | 149 | _content = (UINT32) fat_sector[off]; 150 | 151 | fat_sector = FAT_getblk(sb, ++sec); 152 | if (!fat_sector) 153 | return -1; 154 | 155 | _content |= (UINT32) fat_sector[0] << 8; 156 | } else { 157 | fat_sector = FAT_getblk(sb, sec); 158 | if (!fat_sector) 159 | return -1; 160 | 161 | fat_entry = &(fat_sector[off]); 162 | _content = GET16(fat_entry); 163 | } 164 | 165 | if (loc & 1) _content >>= 4; 166 | 167 | _content &= 0x00000FFF; 168 | 169 | if (_content >= CLUSTER_16(0x0FF8)) { 170 | *content = CLUSTER_32(~0); 171 | return 0; 172 | } else { 173 | *content = CLUSTER_32(_content); 174 | return 0; 175 | } 176 | } else if (p_fs->vol_type == FAT16) { 177 | sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-1)); 178 | off = (loc << 1) & p_bd->sector_size_mask; 179 | 180 | fat_sector = FAT_getblk(sb, sec); 181 | if 182 | (!fat_sector) 183 | return -1; 184 | 185 | fat_entry = &(fat_sector[off]); 186 | 187 | _content = GET16_A(fat_entry); 188 | 189 | _content &= 0x0000FFFF; 190 | 191 | if (_content >= CLUSTER_16(0xFFF8)) { 192 | *content = CLUSTER_32(~0); 193 | return 0; 194 | } else { 195 | *content = CLUSTER_32(_content); 196 | return 0; 197 | } 198 | } else if (p_fs->vol_type == FAT32) { 199 | sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-2)); 200 | off = (loc << 2) & p_bd->sector_size_mask; 201 | 202 | fat_sector = FAT_getblk(sb, sec); 203 | if (!fat_sector) 204 | return -1; 205 | 206 | fat_entry = &(fat_sector[off]); 207 | 208 | _content = GET32_A(fat_entry); 209 | 210 | _content &= 0x0FFFFFFF; 211 | 212 | if (_content >= CLUSTER_32(0x0FFFFFF8)) { 213 | *content = CLUSTER_32(~0); 214 | return 0; 215 | } else { 216 | *content = CLUSTER_32(_content); 217 | return 0; 218 | } 219 | } else { 220 | sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-2)); 221 | off = (loc << 2) & p_bd->sector_size_mask; 222 | 223 | fat_sector = FAT_getblk(sb, sec); 224 | if (!fat_sector) 225 | return -1; 226 | 227 | fat_entry = &(fat_sector[off]); 228 | _content = GET32_A(fat_entry); 229 | 230 | if (_content >= CLUSTER_32(0xFFFFFFF8)) { 231 | *content = CLUSTER_32(~0); 232 | return 0; 233 | } else { 234 | *content = CLUSTER_32(_content); 235 | return 0; 236 | } 237 | } 238 | 239 | *content = CLUSTER_32(~0); 240 | return 0; 241 | } 242 | 243 | static INT32 __FAT_write(struct super_block *sb, UINT32 loc, UINT32 content) 244 | { 245 | INT32 off; 246 | SECTOR sec; 247 | UINT8 *fat_sector, *fat_entry; 248 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 249 | BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info); 250 | 251 | if (p_fs->vol_type == FAT12) { 252 | 253 | content &= 0x00000FFF; 254 | 255 | sec = p_fs->FAT1_start_sector + ((loc + (loc >> 1)) >> p_bd->sector_size_bits); 256 | off = (loc + (loc >> 1)) & p_bd->sector_size_mask; 257 | 258 | fat_sector = FAT_getblk(sb, sec); 259 | if (!fat_sector) 260 | return -1; 261 | 262 | if (loc & 1) { 263 | 264 | content <<= 4; 265 | 266 | if (off == (p_bd->sector_size-1)) { 267 | fat_sector[off] = (UINT8)(content | (fat_sector[off] & 0x0F)); 268 | FAT_modify(sb, sec); 269 | 270 | fat_sector = FAT_getblk(sb, ++sec); 271 | if (!fat_sector) 272 | return -1; 273 | 274 | fat_sector[0] = (UINT8)(content >> 8); 275 | } else { 276 | fat_entry = &(fat_sector[off]); 277 | content |= GET16(fat_entry) & 0x000F; 278 | 279 | SET16(fat_entry, content); 280 | } 281 | } else { 282 | fat_sector[off] = (UINT8)(content); 283 | 284 | if (off == (p_bd->sector_size-1)) { 285 | fat_sector[off] = (UINT8)(content); 286 | FAT_modify(sb, sec); 287 | 288 | fat_sector = FAT_getblk(sb, ++sec); 289 | fat_sector[0] = (UINT8)((fat_sector[0] & 0xF0) | (content >> 8)); 290 | } else { 291 | fat_entry = &(fat_sector[off]); 292 | content |= GET16(fat_entry) & 0xF000; 293 | 294 | SET16(fat_entry, content); 295 | } 296 | } 297 | } 298 | 299 | else if (p_fs->vol_type == FAT16) { 300 | 301 | content &= 0x0000FFFF; 302 | 303 | sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-1)); 304 | off = (loc << 1) & p_bd->sector_size_mask; 305 | 306 | fat_sector = FAT_getblk(sb, sec); 307 | if (!fat_sector) 308 | return -1; 309 | 310 | fat_entry = &(fat_sector[off]); 311 | 312 | SET16_A(fat_entry, content); 313 | } 314 | 315 | else if (p_fs->vol_type == FAT32) { 316 | 317 | content &= 0x0FFFFFFF; 318 | 319 | sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-2)); 320 | off = (loc << 2) & p_bd->sector_size_mask; 321 | 322 | fat_sector = FAT_getblk(sb, sec); 323 | if (!fat_sector) 324 | return -1; 325 | 326 | fat_entry = &(fat_sector[off]); 327 | 328 | content |= GET32_A(fat_entry) & 0xF0000000; 329 | 330 | SET32_A(fat_entry, content); 331 | } 332 | 333 | else { 334 | 335 | sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-2)); 336 | off = (loc << 2) & p_bd->sector_size_mask; 337 | 338 | fat_sector = FAT_getblk(sb, sec); 339 | if (!fat_sector) 340 | return -1; 341 | 342 | fat_entry = &(fat_sector[off]); 343 | 344 | SET32_A(fat_entry, content); 345 | } 346 | 347 | FAT_modify(sb, sec); 348 | return 0; 349 | } 350 | 351 | UINT8 *FAT_getblk(struct super_block *sb, SECTOR sec) 352 | { 353 | BUF_CACHE_T *bp; 354 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 355 | 356 | bp = FAT_cache_find(sb, sec); 357 | if (bp != NULL) { 358 | move_to_mru(bp, &p_fs->FAT_cache_lru_list); 359 | return(bp->buf_bh->b_data); 360 | } 361 | 362 | bp = FAT_cache_get(sb, sec); 363 | 364 | FAT_cache_remove_hash(bp); 365 | 366 | bp->drv = p_fs->drv; 367 | bp->sec = sec; 368 | bp->flag = 0; 369 | 370 | FAT_cache_insert_hash(sb, bp); 371 | 372 | if (sector_read(sb, sec, &(bp->buf_bh), 1) != FFS_SUCCESS) { 373 | FAT_cache_remove_hash(bp); 374 | bp->drv = -1; 375 | bp->sec = ~0; 376 | bp->flag = 0; 377 | bp->buf_bh = NULL; 378 | 379 | move_to_lru(bp, &p_fs->FAT_cache_lru_list); 380 | return NULL; 381 | } 382 | 383 | return(bp->buf_bh->b_data); 384 | } 385 | 386 | void FAT_modify(struct super_block *sb, SECTOR sec) 387 | { 388 | BUF_CACHE_T *bp; 389 | 390 | bp = FAT_cache_find(sb, sec); 391 | if (bp != NULL) { 392 | sector_write(sb, sec, bp->buf_bh, 0); 393 | } 394 | } 395 | 396 | void FAT_release_all(struct super_block *sb) 397 | { 398 | BUF_CACHE_T *bp; 399 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 400 | 401 | sm_P(&f_sem); 402 | 403 | bp = p_fs->FAT_cache_lru_list.next; 404 | while (bp != &p_fs->FAT_cache_lru_list) { 405 | if (bp->drv == p_fs->drv) { 406 | bp->drv = -1; 407 | bp->sec = ~0; 408 | bp->flag = 0; 409 | 410 | if(bp->buf_bh) { 411 | __brelse(bp->buf_bh); 412 | bp->buf_bh = NULL; 413 | } 414 | } 415 | bp = bp->next; 416 | } 417 | 418 | sm_V(&f_sem); 419 | } 420 | 421 | void FAT_sync(struct super_block *sb) 422 | { 423 | BUF_CACHE_T *bp; 424 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 425 | 426 | sm_P(&f_sem); 427 | 428 | bp = p_fs->FAT_cache_lru_list.next; 429 | while (bp != &p_fs->FAT_cache_lru_list) { 430 | if ((bp->drv == p_fs->drv) && (bp->flag & DIRTYBIT)) { 431 | sync_dirty_buffer(bp->buf_bh); 432 | bp->flag &= ~(DIRTYBIT); 433 | } 434 | bp = bp->next; 435 | } 436 | 437 | sm_V(&f_sem); 438 | } 439 | 440 | static BUF_CACHE_T *FAT_cache_find(struct super_block *sb, SECTOR sec) 441 | { 442 | INT32 off; 443 | BUF_CACHE_T *bp, *hp; 444 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 445 | 446 | off = (sec + (sec >> p_fs->sectors_per_clu_bits)) & (FAT_CACHE_HASH_SIZE - 1); 447 | 448 | hp = &(p_fs->FAT_cache_hash_list[off]); 449 | for (bp = hp->hash_next; bp != hp; bp = bp->hash_next) { 450 | if ((bp->drv == p_fs->drv) && (bp->sec == sec)) { 451 | 452 | WARN(!bp->buf_bh, "[EXFAT] FAT_cache has no bh. " 453 | "It will make system panic.\n"); 454 | 455 | touch_buffer(bp->buf_bh); 456 | return(bp); 457 | } 458 | } 459 | return(NULL); 460 | } 461 | 462 | static BUF_CACHE_T *FAT_cache_get(struct super_block *sb, SECTOR sec) 463 | { 464 | BUF_CACHE_T *bp; 465 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 466 | 467 | bp = p_fs->FAT_cache_lru_list.prev; 468 | 469 | 470 | move_to_mru(bp, &p_fs->FAT_cache_lru_list); 471 | return(bp); 472 | } 473 | 474 | static void FAT_cache_insert_hash(struct super_block *sb, BUF_CACHE_T *bp) 475 | { 476 | INT32 off; 477 | BUF_CACHE_T *hp; 478 | FS_INFO_T *p_fs; 479 | 480 | p_fs = &(EXFAT_SB(sb)->fs_info); 481 | off = (bp->sec + (bp->sec >> p_fs->sectors_per_clu_bits)) & (FAT_CACHE_HASH_SIZE-1); 482 | 483 | hp = &(p_fs->FAT_cache_hash_list[off]); 484 | bp->hash_next = hp->hash_next; 485 | bp->hash_prev = hp; 486 | hp->hash_next->hash_prev = bp; 487 | hp->hash_next = bp; 488 | } 489 | 490 | static void FAT_cache_remove_hash(BUF_CACHE_T *bp) 491 | { 492 | (bp->hash_prev)->hash_next = bp->hash_next; 493 | (bp->hash_next)->hash_prev = bp->hash_prev; 494 | } 495 | 496 | UINT8 *buf_getblk(struct super_block *sb, SECTOR sec) 497 | { 498 | UINT8 *buf; 499 | 500 | sm_P(&b_sem); 501 | 502 | buf = __buf_getblk(sb, sec); 503 | 504 | sm_V(&b_sem); 505 | 506 | return(buf); 507 | } 508 | 509 | static UINT8 *__buf_getblk(struct super_block *sb, SECTOR sec) 510 | { 511 | BUF_CACHE_T *bp; 512 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 513 | 514 | bp = buf_cache_find(sb, sec); 515 | if (bp != NULL) { 516 | move_to_mru(bp, &p_fs->buf_cache_lru_list); 517 | return(bp->buf_bh->b_data); 518 | } 519 | 520 | bp = buf_cache_get(sb, sec); 521 | 522 | buf_cache_remove_hash(bp); 523 | 524 | bp->drv = p_fs->drv; 525 | bp->sec = sec; 526 | bp->flag = 0; 527 | 528 | buf_cache_insert_hash(sb, bp); 529 | 530 | if (sector_read(sb, sec, &(bp->buf_bh), 1) != FFS_SUCCESS) { 531 | buf_cache_remove_hash(bp); 532 | bp->drv = -1; 533 | bp->sec = ~0; 534 | bp->flag = 0; 535 | bp->buf_bh = NULL; 536 | 537 | move_to_lru(bp, &p_fs->buf_cache_lru_list); 538 | return NULL; 539 | } 540 | 541 | return(bp->buf_bh->b_data); 542 | 543 | } 544 | 545 | void buf_modify(struct super_block *sb, SECTOR sec) 546 | { 547 | BUF_CACHE_T *bp; 548 | 549 | sm_P(&b_sem); 550 | 551 | bp = buf_cache_find(sb, sec); 552 | if (likely(bp != NULL)) { 553 | sector_write(sb, sec, bp->buf_bh, 0); 554 | } 555 | 556 | WARN(!bp, "[EXFAT] failed to find buffer_cache! (sec = 0x%lX)\n", sec); 557 | 558 | sm_V(&b_sem); 559 | } 560 | 561 | void buf_lock(struct super_block *sb, SECTOR sec) 562 | { 563 | BUF_CACHE_T *bp; 564 | 565 | sm_P(&b_sem); 566 | 567 | bp = buf_cache_find(sb, sec); 568 | if (likely(bp != NULL)) bp->flag |= LOCKBIT; 569 | 570 | WARN(!bp, "[EXFAT] failed to find buffer_cache! (sec = 0x%lX)\n", sec); 571 | 572 | sm_V(&b_sem); 573 | } 574 | 575 | void buf_unlock(struct super_block *sb, SECTOR sec) 576 | { 577 | BUF_CACHE_T *bp; 578 | 579 | sm_P(&b_sem); 580 | 581 | bp = buf_cache_find(sb, sec); 582 | if (likely(bp != NULL)) bp->flag &= ~(LOCKBIT); 583 | 584 | WARN(!bp, "[EXFAT] failed to find buffer_cache! (sec = 0x%lX)\n", sec); 585 | 586 | sm_V(&b_sem); 587 | } 588 | 589 | void buf_release(struct super_block *sb, SECTOR sec) 590 | { 591 | BUF_CACHE_T *bp; 592 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 593 | 594 | sm_P(&b_sem); 595 | 596 | bp = buf_cache_find(sb, sec); 597 | if (likely(bp != NULL)) { 598 | bp->drv = -1; 599 | bp->sec = ~0; 600 | bp->flag = 0; 601 | 602 | if(bp->buf_bh) { 603 | __brelse(bp->buf_bh); 604 | bp->buf_bh = NULL; 605 | } 606 | 607 | move_to_lru(bp, &p_fs->buf_cache_lru_list); 608 | } 609 | 610 | sm_V(&b_sem); 611 | } 612 | 613 | void buf_release_all(struct super_block *sb) 614 | { 615 | BUF_CACHE_T *bp; 616 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 617 | 618 | sm_P(&b_sem); 619 | 620 | bp = p_fs->buf_cache_lru_list.next; 621 | while (bp != &p_fs->buf_cache_lru_list) { 622 | if (bp->drv == p_fs->drv) { 623 | bp->drv = -1; 624 | bp->sec = ~0; 625 | bp->flag = 0; 626 | 627 | if(bp->buf_bh) { 628 | __brelse(bp->buf_bh); 629 | bp->buf_bh = NULL; 630 | } 631 | } 632 | bp = bp->next; 633 | } 634 | 635 | sm_V(&b_sem); 636 | } 637 | 638 | void buf_sync(struct super_block *sb) 639 | { 640 | BUF_CACHE_T *bp; 641 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 642 | 643 | sm_P(&b_sem); 644 | 645 | bp = p_fs->buf_cache_lru_list.next; 646 | while (bp != &p_fs->buf_cache_lru_list) { 647 | if ((bp->drv == p_fs->drv) && (bp->flag & DIRTYBIT)) { 648 | sync_dirty_buffer(bp->buf_bh); 649 | bp->flag &= ~(DIRTYBIT); 650 | } 651 | bp = bp->next; 652 | } 653 | 654 | sm_V(&b_sem); 655 | } 656 | 657 | static BUF_CACHE_T *buf_cache_find(struct super_block *sb, SECTOR sec) 658 | { 659 | INT32 off; 660 | BUF_CACHE_T *bp, *hp; 661 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 662 | 663 | off = (sec + (sec >> p_fs->sectors_per_clu_bits)) & (BUF_CACHE_HASH_SIZE - 1); 664 | 665 | hp = &(p_fs->buf_cache_hash_list[off]); 666 | for (bp = hp->hash_next; bp != hp; bp = bp->hash_next) { 667 | if ((bp->drv == p_fs->drv) && (bp->sec == sec)) { 668 | touch_buffer(bp->buf_bh); 669 | return(bp); 670 | } 671 | } 672 | return(NULL); 673 | } 674 | 675 | static BUF_CACHE_T *buf_cache_get(struct super_block *sb, SECTOR sec) 676 | { 677 | BUF_CACHE_T *bp; 678 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 679 | 680 | bp = p_fs->buf_cache_lru_list.prev; 681 | while (bp->flag & LOCKBIT) bp = bp->prev; 682 | 683 | 684 | move_to_mru(bp, &p_fs->buf_cache_lru_list); 685 | return(bp); 686 | } 687 | 688 | static void buf_cache_insert_hash(struct super_block *sb, BUF_CACHE_T *bp) 689 | { 690 | INT32 off; 691 | BUF_CACHE_T *hp; 692 | FS_INFO_T *p_fs; 693 | 694 | p_fs = &(EXFAT_SB(sb)->fs_info); 695 | off = (bp->sec + (bp->sec >> p_fs->sectors_per_clu_bits)) & (BUF_CACHE_HASH_SIZE-1); 696 | 697 | hp = &(p_fs->buf_cache_hash_list[off]); 698 | bp->hash_next = hp->hash_next; 699 | bp->hash_prev = hp; 700 | hp->hash_next->hash_prev = bp; 701 | hp->hash_next = bp; 702 | } 703 | 704 | static void buf_cache_remove_hash(BUF_CACHE_T *bp) 705 | { 706 | (bp->hash_prev)->hash_next = bp->hash_next; 707 | (bp->hash_next)->hash_prev = bp->hash_prev; 708 | } 709 | 710 | static void push_to_mru(BUF_CACHE_T *bp, BUF_CACHE_T *list) 711 | { 712 | bp->next = list->next; 713 | bp->prev = list; 714 | list->next->prev = bp; 715 | list->next = bp; 716 | } 717 | 718 | static void push_to_lru(BUF_CACHE_T *bp, BUF_CACHE_T *list) 719 | { 720 | bp->prev = list->prev; 721 | bp->next = list; 722 | list->prev->next = bp; 723 | list->prev = bp; 724 | } 725 | 726 | static void move_to_mru(BUF_CACHE_T *bp, BUF_CACHE_T *list) 727 | { 728 | bp->prev->next = bp->next; 729 | bp->next->prev = bp->prev; 730 | push_to_mru(bp, list); 731 | } 732 | 733 | static void move_to_lru(BUF_CACHE_T *bp, BUF_CACHE_T *list) 734 | { 735 | bp->prev->next = bp->next; 736 | bp->next->prev = bp->prev; 737 | push_to_lru(bp, list); 738 | } 739 | 740 | INT32 buf_cache_readahead(struct super_block * sb, SECTOR sec) 741 | { 742 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 743 | struct buffer_head *bh; 744 | UINT32 max_ra_count = DCACHE_MAX_RA_SIZE >> sb->s_blocksize_bits; 745 | UINT32 page_ra_count = PAGE_SIZE >> sb->s_blocksize_bits; 746 | UINT32 adj_ra_count = max(p_fs->sectors_per_clu, page_ra_count); 747 | UINT32 ra_count = min(adj_ra_count, max_ra_count); 748 | 749 | if (p_fs->sectors_per_clu == 1) 750 | return 0; 751 | 752 | if (sec < p_fs->data_start_sector) 753 | return (FFS_MEDIAERR); 754 | 755 | /* Not sector aligned with ra_count, resize ra_count to page size */ 756 | if ((sec - p_fs->data_start_sector) & (ra_count - 1)) 757 | ra_count = page_ra_count; 758 | 759 | bh = sb_find_get_block(sb, sec); 760 | if (!bh || !buffer_uptodate(bh)) 761 | bdev_reada(sb, sec, ra_count); 762 | 763 | brelse(bh); 764 | 765 | return 0; 766 | } 767 | -------------------------------------------------------------------------------- /exfat_cache.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation; either version 2 7 | * of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | #ifndef _EXFAT_CACHE_H 20 | #define _EXFAT_CACHE_H 21 | 22 | #include "exfat_global.h" 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | #define LOCKBIT 0x01 29 | #define DIRTYBIT 0x02 30 | 31 | #define DCACHE_MAX_RA_SIZE (128*1024) 32 | 33 | typedef struct __BUF_CACHE_T { 34 | struct __BUF_CACHE_T *next; 35 | struct __BUF_CACHE_T *prev; 36 | struct __BUF_CACHE_T *hash_next; 37 | struct __BUF_CACHE_T *hash_prev; 38 | INT32 drv; 39 | SECTOR sec; 40 | UINT32 flag; 41 | struct buffer_head *buf_bh; 42 | } BUF_CACHE_T; 43 | 44 | INT32 buf_init(struct super_block *sb); 45 | INT32 buf_shutdown(struct super_block *sb); 46 | INT32 FAT_read(struct super_block *sb, UINT32 loc, UINT32 *content); 47 | INT32 FAT_write(struct super_block *sb, UINT32 loc, UINT32 content); 48 | UINT8 *FAT_getblk(struct super_block *sb, SECTOR sec); 49 | void FAT_modify(struct super_block *sb, SECTOR sec); 50 | void FAT_release_all(struct super_block *sb); 51 | void FAT_sync(struct super_block *sb); 52 | UINT8 *buf_getblk(struct super_block *sb, SECTOR sec); 53 | void buf_modify(struct super_block *sb, SECTOR sec); 54 | void buf_lock(struct super_block *sb, SECTOR sec); 55 | void buf_unlock(struct super_block *sb, SECTOR sec); 56 | void buf_release(struct super_block *sb, SECTOR sec); 57 | void buf_release_all(struct super_block *sb); 58 | void buf_sync(struct super_block *sb); 59 | INT32 buf_cache_readahead(struct super_block * sb, SECTOR sec); 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /exfat_data.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation; either version 2 7 | * of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | #include "exfat_global.h" 20 | #include "exfat_data.h" 21 | #include "exfat_oal.h" 22 | 23 | #include "exfat_blkdev.h" 24 | #include "exfat_cache.h" 25 | #include "exfat_nls.h" 26 | #include "exfat_super.h" 27 | #include "exfat.h" 28 | 29 | FS_STRUCT_T fs_struct[MAX_DRIVE]; 30 | 31 | DECLARE_MUTEX(f_sem); 32 | BUF_CACHE_T FAT_cache_array[FAT_CACHE_SIZE]; 33 | BUF_CACHE_T FAT_cache_lru_list; 34 | BUF_CACHE_T FAT_cache_hash_list[FAT_CACHE_HASH_SIZE]; 35 | 36 | DECLARE_MUTEX(b_sem); 37 | BUF_CACHE_T buf_cache_array[BUF_CACHE_SIZE]; 38 | BUF_CACHE_T buf_cache_lru_list; 39 | BUF_CACHE_T buf_cache_hash_list[BUF_CACHE_HASH_SIZE]; 40 | -------------------------------------------------------------------------------- /exfat_data.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation; either version 2 7 | * of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | #ifndef _EXFAT_DATA_H 20 | #define _EXFAT_DATA_H 21 | #include "exfat_global.h" 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | #define MAX_DEVICE 2 26 | #define MAX_DRIVE 4 27 | #define MAX_OPEN 20 28 | #define MAX_DENTRY 512 29 | #define FAT_CACHE_SIZE 128 30 | #define FAT_CACHE_HASH_SIZE 64 31 | #define BUF_CACHE_SIZE 256 32 | #define BUF_CACHE_HASH_SIZE 64 33 | #ifdef __cplusplus 34 | } 35 | #endif 36 | #endif 37 | -------------------------------------------------------------------------------- /exfat_global.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation; either version 2 7 | * of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | #include "exfat_global.h" 20 | 21 | INT32 __wstrchr(UINT16 *str, UINT16 wchar) 22 | { 23 | while (*str) { 24 | if (*(str++) == wchar) return(1); 25 | } 26 | return(0); 27 | } 28 | 29 | INT32 __wstrlen(UINT16 *str) 30 | { 31 | INT32 length = 0; 32 | 33 | while (*(str++)) length++; 34 | return(length); 35 | } 36 | 37 | #define BITMAP_LOC(v) ((v) >> 3) 38 | #define BITMAP_SHIFT(v) ((v) & 0x07) 39 | 40 | void Bitmap_set_all(UINT8 *bitmap, INT32 mapsize) 41 | { 42 | MEMSET(bitmap, 0xFF, mapsize); 43 | } 44 | 45 | void Bitmap_clear_all(UINT8 *bitmap, INT32 mapsize) 46 | { 47 | MEMSET(bitmap, 0x0, mapsize); 48 | } 49 | 50 | INT32 Bitmap_test(UINT8 *bitmap, INT32 i) 51 | { 52 | UINT8 data; 53 | 54 | data = bitmap[BITMAP_LOC(i)]; 55 | if ((data >> BITMAP_SHIFT(i)) & 0x01) return(1); 56 | return(0); 57 | } 58 | 59 | void Bitmap_set(UINT8 *bitmap, INT32 i) 60 | { 61 | bitmap[BITMAP_LOC(i)] |= (0x01 << BITMAP_SHIFT(i)); 62 | } 63 | 64 | void Bitmap_clear(UINT8 *bitmap, INT32 i) 65 | { 66 | bitmap[BITMAP_LOC(i)] &= ~(0x01 << BITMAP_SHIFT(i)); 67 | } 68 | 69 | void Bitmap_nbits_set(UINT8 *bitmap, INT32 offset, INT32 nbits) 70 | { 71 | INT32 i; 72 | 73 | for (i = 0; i < nbits; i++) { 74 | Bitmap_set(bitmap, offset+i); 75 | } 76 | } 77 | 78 | void Bitmap_nbits_clear(UINT8 *bitmap, INT32 offset, INT32 nbits) 79 | { 80 | INT32 i; 81 | 82 | for (i = 0; i < nbits; i++) { 83 | Bitmap_clear(bitmap, offset+i); 84 | } 85 | } 86 | 87 | void my_itoa(INT8 *buf, INT32 v) 88 | { 89 | INT32 mod[10]; 90 | INT32 i; 91 | 92 | for (i = 0; i < 10; i++) { 93 | mod[i] = (v % 10); 94 | v = v / 10; 95 | if (v == 0) break; 96 | } 97 | 98 | if (i == 10) 99 | i--; 100 | 101 | for (; i >= 0; i--) { 102 | *buf = (UINT8) ('0' + mod[i]); 103 | buf++; 104 | } 105 | *buf = '\0'; 106 | } 107 | 108 | INT32 my_log2(UINT32 v) 109 | { 110 | UINT32 bits = 0; 111 | 112 | while (v > 1) { 113 | if (v & 0x01) return(-1); 114 | v >>= 1; 115 | bits++; 116 | } 117 | return(bits); 118 | } 119 | -------------------------------------------------------------------------------- /exfat_global.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation; either version 2 7 | * of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | #ifndef _EXFAT_GLOBAL_H 20 | #define _EXFAT_GLOBAL_H 21 | 22 | #define pr_fmt(fmt) "%s: %s: " fmt, KBUILD_MODNAME, __func__ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | #ifndef TRUE 35 | #define TRUE 1 36 | #endif 37 | #ifndef FALSE 38 | #define FALSE 0 39 | #endif 40 | #ifndef OK 41 | #define OK 0 42 | #endif 43 | #ifndef FAIL 44 | #define FAIL 1 45 | #endif 46 | #ifndef NULL 47 | #define NULL 0 48 | #endif 49 | 50 | #define MIN(a, b) (((a) < (b)) ? (a) : (b)) 51 | #define MAX(a, b) (((a) > (b)) ? (a) : (b)) 52 | 53 | typedef char INT8; 54 | typedef short INT16; 55 | typedef int INT32; 56 | typedef long long INT64; 57 | typedef unsigned char UINT8; 58 | typedef unsigned short UINT16; 59 | typedef unsigned int UINT32; 60 | typedef unsigned long long UINT64; 61 | typedef unsigned char BOOL; 62 | typedef sector_t SECTOR; 63 | 64 | #ifdef MALLOC 65 | #undef MALLOC 66 | #endif 67 | #ifdef FREE 68 | #undef FREE 69 | #endif 70 | #ifdef MEMSET 71 | #undef MEMSET 72 | #endif 73 | #ifdef MEMCPY 74 | #undef MEMCPY 75 | #endif 76 | #ifdef MEMCMP 77 | #undef MEMCMP 78 | #endif 79 | 80 | #define MALLOC(size) kmalloc(size, GFP_KERNEL) 81 | #define FREE(mem) if (mem) kfree(mem) 82 | #define MEMSET(mem, value, size) memset(mem, value, size) 83 | #define MEMCPY(dest, src, size) memcpy(dest, src, size) 84 | #define MEMCMP(mem1, mem2, size) memcmp(mem1, mem2, size) 85 | #define COPY_DENTRY(dest, src) memcpy(dest, src, sizeof(DENTRY_T)) 86 | 87 | #define STRCPY(dest, src) strcpy(dest, src) 88 | #define STRNCPY(dest, src, n) strncpy(dest, src, n) 89 | #define STRCAT(str1, str2) strcat(str1, str2) 90 | #define STRCMP(str1, str2) strcmp(str1, str2) 91 | #define STRNCMP(str1, str2, n) strncmp(str1, str2, n) 92 | #define STRDUP(str) kstrdup(str, GFP_KERNEL) 93 | #define STRLEN(str) strlen(str) 94 | 95 | INT32 __wstrchr(UINT16 *str, UINT16 wchar); 96 | INT32 __wstrlen(UINT16 *str); 97 | 98 | #define WSTRCHR(str, wchar) __wstrchr(str, wchar) 99 | #define WSTRLEN(str) __wstrlen(str) 100 | 101 | #define PANIC(fmt, ...) panic(pr_fmt(fmt), ##__VA_ARGS__) 102 | #define LOG(level, fmt, ...) printk("%s" pr_fmt(fmt), level, ##__VA_ARGS__) 103 | 104 | #define LOGE pr_err 105 | #define LOGW pr_warn 106 | #define LOGI pr_info 107 | #ifdef CONFIG_EXFAT_DEBUG 108 | #define LOGD pr_debug 109 | #else 110 | #define LOGD(...) 111 | #endif 112 | 113 | void Bitmap_set_all(UINT8 *bitmap, INT32 mapsize); 114 | void Bitmap_clear_all(UINT8 *bitmap, INT32 mapsize); 115 | INT32 Bitmap_test(UINT8 *bitmap, INT32 i); 116 | void Bitmap_set(UINT8 *bitmap, INT32 i); 117 | void Bitmap_clear(UINT8 *bitmpa, INT32 i); 118 | void Bitmap_nbits_set(UINT8 *bitmap, INT32 offset, INT32 nbits); 119 | void Bitmap_nbits_clear(UINT8 *bitmap, INT32 offset, INT32 nbits); 120 | 121 | void my_itoa(INT8 *buf, INT32 v); 122 | INT32 my_log2(UINT32 v); 123 | 124 | #ifdef __cplusplus 125 | } 126 | #endif 127 | #endif 128 | -------------------------------------------------------------------------------- /exfat_nls.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation; either version 2 7 | * of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | #include "exfat_global.h" 20 | #include "exfat_data.h" 21 | 22 | #include "exfat_nls.h" 23 | #include "exfat_api.h" 24 | #include "exfat_super.h" 25 | #include "exfat.h" 26 | 27 | #include 28 | 29 | static UINT16 bad_dos_chars[] = { 30 | 0x002B, 0x002C, 0x003B, 0x003D, 0x005B, 0x005D, 31 | 0xFF0B, 0xFF0C, 0xFF1B, 0xFF1D, 0xFF3B, 0xFF3D, 32 | 0 33 | }; 34 | 35 | static UINT16 bad_uni_chars[] = { 36 | 0x0022, 0x002A, 0x002F, 0x003A, 37 | 0x003C, 0x003E, 0x003F, 0x005C, 0x007C, 38 | 0 39 | }; 40 | 41 | static INT32 convert_uni_to_ch(struct nls_table *nls, UINT8 *ch, UINT16 uni, INT32 *lossy); 42 | static INT32 convert_ch_to_uni(struct nls_table *nls, UINT16 *uni, UINT8 *ch, INT32 *lossy); 43 | 44 | UINT16 nls_upper(struct super_block *sb, UINT16 a) 45 | { 46 | FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info); 47 | 48 | if (EXFAT_SB(sb)->options.casesensitive) 49 | return(a); 50 | if ((p_fs->vol_utbl)[get_col_index(a)] != NULL) 51 | return (p_fs->vol_utbl)[get_col_index(a)][get_row_index(a)]; 52 | else 53 | return a; 54 | } 55 | 56 | INT32 nls_dosname_cmp(struct super_block *sb, UINT8 *a, UINT8 *b) 57 | { 58 | return(STRNCMP((void *) a, (void *) b, DOS_NAME_LENGTH)); 59 | } 60 | 61 | INT32 nls_uniname_cmp(struct super_block *sb, UINT16 *a, UINT16 *b) 62 | { 63 | INT32 i; 64 | 65 | for (i = 0; i < MAX_NAME_LENGTH; i++, a++, b++) { 66 | if (nls_upper(sb, *a) != nls_upper(sb, *b)) return(1); 67 | if (*a == 0x0) return(0); 68 | } 69 | return(0); 70 | } 71 | 72 | void nls_uniname_to_dosname(struct super_block *sb, DOS_NAME_T *p_dosname, UNI_NAME_T *p_uniname, INT32 *p_lossy) 73 | { 74 | INT32 i, j, len, lossy = FALSE; 75 | UINT8 buf[MAX_CHARSET_SIZE]; 76 | UINT8 lower = 0, upper = 0; 77 | UINT8 *dosname = p_dosname->name; 78 | UINT16 *uniname = p_uniname->name; 79 | UINT16 *p, *last_period; 80 | struct nls_table *nls = EXFAT_SB(sb)->nls_disk; 81 | 82 | for (i = 0; i < DOS_NAME_LENGTH; i++) { 83 | *(dosname+i) = ' '; 84 | } 85 | 86 | if (!nls_uniname_cmp(sb, uniname, (UINT16 *) UNI_CUR_DIR_NAME)) { 87 | *(dosname) = '.'; 88 | p_dosname->name_case = 0x0; 89 | if (p_lossy != NULL) *p_lossy = FALSE; 90 | return; 91 | } 92 | 93 | if (!nls_uniname_cmp(sb, uniname, (UINT16 *) UNI_PAR_DIR_NAME)) { 94 | *(dosname) = '.'; 95 | *(dosname+1) = '.'; 96 | p_dosname->name_case = 0x0; 97 | if (p_lossy != NULL) *p_lossy = FALSE; 98 | return; 99 | } 100 | 101 | last_period = NULL; 102 | for (p = uniname; *p; p++) { 103 | if (*p == (UINT16) '.') last_period = p; 104 | } 105 | 106 | i = 0; 107 | while (i < DOS_NAME_LENGTH) { 108 | if (i == 8) { 109 | if (last_period == NULL) break; 110 | 111 | if (uniname <= last_period) { 112 | if (uniname < last_period) lossy = TRUE; 113 | uniname = last_period + 1; 114 | } 115 | } 116 | 117 | if (*uniname == (UINT16) '\0') { 118 | break; 119 | } else if (*uniname == (UINT16) ' ') { 120 | lossy = TRUE; 121 | } else if (*uniname == (UINT16) '.') { 122 | if (uniname < last_period) lossy = TRUE; 123 | else i = 8; 124 | } else if (WSTRCHR(bad_dos_chars, *uniname)) { 125 | lossy = TRUE; 126 | *(dosname+i) = '_'; 127 | i++; 128 | } else { 129 | len = convert_uni_to_ch(nls, buf, *uniname, &lossy); 130 | 131 | if (len > 1) { 132 | if ((i >= 8) && ((i+len) > DOS_NAME_LENGTH)) { 133 | break; 134 | } 135 | if ((i < 8) && ((i+len) > 8)) { 136 | i = 8; 137 | continue; 138 | } 139 | 140 | lower = 0xFF; 141 | 142 | for (j = 0; j < len; j++, i++) { 143 | *(dosname+i) = *(buf+j); 144 | } 145 | } else { 146 | if ((*buf >= 'a') && (*buf <= 'z')) { 147 | *(dosname+i) = *buf - ('a' - 'A'); 148 | 149 | if (i < 8) lower |= 0x08; 150 | else lower |= 0x10; 151 | } else if ((*buf >= 'A') && (*buf <= 'Z')) { 152 | *(dosname+i) = *buf; 153 | 154 | if (i < 8) upper |= 0x08; 155 | else upper |= 0x10; 156 | } else { 157 | *(dosname+i) = *buf; 158 | } 159 | i++; 160 | } 161 | } 162 | 163 | uniname++; 164 | } 165 | 166 | if (*dosname == 0xE5) *dosname = 0x05; 167 | if (*uniname != 0x0) lossy = TRUE; 168 | 169 | if (upper & lower) p_dosname->name_case = 0xFF; 170 | else p_dosname->name_case = lower; 171 | 172 | if (p_lossy != NULL) *p_lossy = lossy; 173 | } 174 | 175 | void nls_dosname_to_uniname(struct super_block *sb, UNI_NAME_T *p_uniname, DOS_NAME_T *p_dosname) 176 | { 177 | INT32 i = 0, j, n = 0; 178 | UINT8 buf[DOS_NAME_LENGTH+2]; 179 | UINT8 *dosname = p_dosname->name; 180 | UINT16 *uniname = p_uniname->name; 181 | struct nls_table *nls = EXFAT_SB(sb)->nls_disk; 182 | 183 | if (*dosname == 0x05) { 184 | *buf = 0xE5; 185 | i++; 186 | n++; 187 | } 188 | 189 | for ( ; i < 8; i++, n++) { 190 | if (*(dosname+i) == ' ') break; 191 | 192 | if ((*(dosname+i) >= 'A') && (*(dosname+i) <= 'Z') && (p_dosname->name_case & 0x08)) 193 | *(buf+n) = *(dosname+i) + ('a' - 'A'); 194 | else 195 | *(buf+n) = *(dosname+i); 196 | } 197 | if (*(dosname+8) != ' ') { 198 | *(buf+n) = '.'; 199 | n++; 200 | } 201 | 202 | for (i = 8; i < DOS_NAME_LENGTH; i++, n++) { 203 | if (*(dosname+i) == ' ') break; 204 | 205 | if ((*(dosname+i) >= 'A') && (*(dosname+i) <= 'Z') && (p_dosname->name_case & 0x10)) 206 | *(buf+n) = *(dosname+i) + ('a' - 'A'); 207 | else 208 | *(buf+n) = *(dosname+i); 209 | } 210 | *(buf+n) = '\0'; 211 | 212 | i = j = 0; 213 | while (j < (MAX_NAME_LENGTH-1)) { 214 | if (*(buf+i) == '\0') break; 215 | 216 | i += convert_ch_to_uni(nls, uniname, (buf+i), NULL); 217 | 218 | uniname++; 219 | j++; 220 | } 221 | 222 | *uniname = (UINT16) '\0'; 223 | } 224 | 225 | void nls_uniname_to_cstring(struct super_block *sb, UINT8 *p_cstring, UNI_NAME_T *p_uniname) 226 | { 227 | INT32 i, j, len; 228 | UINT8 buf[MAX_CHARSET_SIZE]; 229 | UINT16 *uniname = p_uniname->name; 230 | struct nls_table *nls = EXFAT_SB(sb)->nls_io; 231 | 232 | i = 0; 233 | while (i < (MAX_NAME_LENGTH-1)) { 234 | if (*uniname == (UINT16) '\0') break; 235 | 236 | len = convert_uni_to_ch(nls, buf, *uniname, NULL); 237 | 238 | if (len > 1) { 239 | for (j = 0; j < len; j++) 240 | *p_cstring++ = (INT8) *(buf+j); 241 | } else { 242 | *p_cstring++ = (INT8) *buf; 243 | } 244 | 245 | uniname++; 246 | i++; 247 | } 248 | 249 | *p_cstring = '\0'; 250 | } 251 | 252 | void nls_cstring_to_uniname(struct super_block *sb, UNI_NAME_T *p_uniname, UINT8 *p_cstring, INT32 *p_lossy) 253 | { 254 | INT32 i, j, lossy = FALSE; 255 | UINT8 *end_of_name; 256 | UINT16 upname[MAX_NAME_LENGTH]; 257 | UINT16 *uniname = p_uniname->name; 258 | struct nls_table *nls = EXFAT_SB(sb)->nls_io; 259 | 260 | end_of_name = p_cstring + STRLEN((INT8 *) p_cstring); 261 | 262 | while (*(--end_of_name) == ' ') { 263 | if (end_of_name < p_cstring) break; 264 | } 265 | *(++end_of_name) = '\0'; 266 | 267 | if (STRCMP((INT8 *) p_cstring, ".") && STRCMP((INT8 *) p_cstring, "..")) { 268 | while (*(--end_of_name) == '.') { 269 | if (end_of_name < p_cstring) break; 270 | } 271 | *(++end_of_name) = '\0'; 272 | } 273 | 274 | if (*p_cstring == '\0') 275 | lossy = TRUE; 276 | 277 | i = j = 0; 278 | while (j < (MAX_NAME_LENGTH-1)) { 279 | if (*(p_cstring+i) == '\0') break; 280 | 281 | i += convert_ch_to_uni(nls, uniname, (UINT8 *)(p_cstring+i), &lossy); 282 | 283 | if ((*uniname < 0x0020) || WSTRCHR(bad_uni_chars, *uniname)) 284 | lossy = TRUE; 285 | 286 | *(upname+j) = nls_upper(sb, *uniname); 287 | 288 | uniname++; 289 | j++; 290 | } 291 | 292 | if (*(p_cstring+i) != '\0') 293 | lossy = TRUE; 294 | *uniname = (UINT16) '\0'; 295 | 296 | p_uniname->name_len = j; 297 | p_uniname->name_hash = calc_checksum_2byte((void *) upname, j<<1, 0, CS_DEFAULT); 298 | 299 | if (p_lossy != NULL) 300 | *p_lossy = lossy; 301 | } 302 | 303 | static INT32 convert_ch_to_uni(struct nls_table *nls, UINT16 *uni, UINT8 *ch, INT32 *lossy) 304 | { 305 | int len; 306 | 307 | *uni = 0x0; 308 | 309 | if (ch[0] < 0x80) { 310 | *uni = (UINT16) ch[0]; 311 | return(1); 312 | } 313 | 314 | if ((len = nls->char2uni(ch, NLS_MAX_CHARSET_SIZE, uni)) < 0) { 315 | LOGW("fail to use nls\n"); 316 | if (lossy != NULL) 317 | *lossy = TRUE; 318 | *uni = (UINT16) '_'; 319 | if (!strcmp(nls->charset, "utf8")) return(1); 320 | else return(2); 321 | } 322 | 323 | return(len); 324 | } 325 | 326 | static INT32 convert_uni_to_ch(struct nls_table *nls, UINT8 *ch, UINT16 uni, INT32 *lossy) 327 | { 328 | int len; 329 | 330 | ch[0] = 0x0; 331 | 332 | if (uni < 0x0080) { 333 | ch[0] = (UINT8) uni; 334 | return(1); 335 | } 336 | 337 | if ((len = nls->uni2char(uni, ch, NLS_MAX_CHARSET_SIZE)) < 0) { 338 | LOGW("fail to use nls\n"); 339 | if (lossy != NULL) *lossy = TRUE; 340 | ch[0] = '_'; 341 | return(1); 342 | } 343 | 344 | return(len); 345 | 346 | } 347 | -------------------------------------------------------------------------------- /exfat_nls.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation; either version 2 7 | * of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | #ifndef _EXFAT_NLS_H 20 | #define _EXFAT_NLS_H 21 | 22 | #include 23 | #include 24 | 25 | #include "exfat_global.h" 26 | #include "exfat_api.h" 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #define NUM_UPCASE 2918 33 | 34 | #define DOS_CUR_DIR_NAME ". " 35 | #define DOS_PAR_DIR_NAME ".. " 36 | 37 | #ifdef __LITTLE_ENDIAN 38 | #define UNI_CUR_DIR_NAME ".\0" 39 | #define UNI_PAR_DIR_NAME ".\0.\0" 40 | #else 41 | #define UNI_CUR_DIR_NAME "\0." 42 | #define UNI_PAR_DIR_NAME "\0.\0." 43 | #endif 44 | 45 | 46 | typedef struct { 47 | UINT8 name[DOS_NAME_LENGTH]; 48 | UINT8 name_case; 49 | } DOS_NAME_T; 50 | 51 | typedef struct { 52 | UINT16 name[MAX_NAME_LENGTH]; 53 | UINT16 name_hash; 54 | UINT8 name_len; 55 | } UNI_NAME_T; 56 | 57 | UINT16 nls_upper(struct super_block *sb, UINT16 a); 58 | INT32 nls_dosname_cmp(struct super_block *sb, UINT8 *a, UINT8 *b); 59 | INT32 nls_uniname_cmp(struct super_block *sb, UINT16 *a, UINT16 *b); 60 | void nls_uniname_to_dosname(struct super_block *sb, DOS_NAME_T *p_dosname, UNI_NAME_T *p_uniname, INT32 *p_lossy); 61 | void nls_dosname_to_uniname(struct super_block *sb, UNI_NAME_T *p_uniname, DOS_NAME_T *p_dosname); 62 | void nls_uniname_to_cstring(struct super_block *sb, UINT8 *p_cstring, UNI_NAME_T *p_uniname); 63 | void nls_cstring_to_uniname(struct super_block *sb, UNI_NAME_T *p_uniname, UINT8 *p_cstring, INT32 *p_lossy); 64 | 65 | #ifdef __cplusplus 66 | } 67 | #endif 68 | #endif 69 | -------------------------------------------------------------------------------- /exfat_oal.c: -------------------------------------------------------------------------------- 1 | /* Some of the source code in this file came from "linux/fs/fat/misc.c". */ 2 | /* 3 | * linux/fs/fat/misc.c 4 | * 5 | * Written 1992,1993 by Werner Almesberger 6 | * 22/11/2000 - Fixed fat_date_unix2dos for dates earlier than 01/01/1980 7 | * and date_dos2unix for date==0 by Igor Zhbanov(bsg@uniyar.ac.ru) 8 | */ 9 | 10 | /* 11 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. 12 | * 13 | * This program is free software; you can redistribute it and/or 14 | * modify it under the terms of the GNU General Public License 15 | * as published by the Free Software Foundation; either version 2 16 | * of the License, or (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software 25 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 | */ 27 | 28 | #include "exfat_global.h" 29 | 30 | #include 31 | #include 32 | 33 | #include "exfat_api.h" 34 | #include "exfat_oal.h" 35 | 36 | DECLARE_MUTEX(z_sem); 37 | 38 | INT32 sm_init(struct semaphore *sm) 39 | { 40 | sema_init(sm, 1); 41 | return(0); 42 | } 43 | 44 | INT32 sm_P(struct semaphore *sm) 45 | { 46 | down(sm); 47 | return 0; 48 | } 49 | 50 | void sm_V(struct semaphore *sm) 51 | { 52 | up(sm); 53 | } 54 | 55 | extern struct timezone sys_tz; 56 | 57 | #define UNIX_SECS_1980 315532800L 58 | 59 | #if BITS_PER_LONG == 64 60 | #define UNIX_SECS_2108 4354819200L 61 | #endif 62 | 63 | #define DAYS_DELTA_DECADE (365 * 10 + 2) 64 | #define NO_LEAP_YEAR_2100 (120) 65 | #define IS_LEAP_YEAR(y) (!((y) & 3) && (y) != NO_LEAP_YEAR_2100) 66 | 67 | #define SECS_PER_MIN (60) 68 | #define SECS_PER_HOUR (60 * SECS_PER_MIN) 69 | #define SECS_PER_DAY (24 * SECS_PER_HOUR) 70 | 71 | #define MAKE_LEAP_YEAR(leap_year, year) \ 72 | do { \ 73 | if (unlikely(year > NO_LEAP_YEAR_2100)) \ 74 | leap_year = ((year + 3) / 4) - 1; \ 75 | else \ 76 | leap_year = ((year + 3) / 4); \ 77 | } while(0) 78 | 79 | 80 | 81 | static time_t accum_days_in_year[] = { 82 | 0, 0, 31, 59, 90,120,151,181,212,243,273,304,334, 0, 0, 0, 83 | }; 84 | 85 | 86 | TIMESTAMP_T *tm_current(TIMESTAMP_T *tp, UINT8 tz_utc) 87 | { 88 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) 89 | time64_t second = ktime_get_real_seconds(); 90 | #else 91 | struct timespec ts = CURRENT_TIME_SEC; 92 | time_t second = ts.tv_sec; 93 | #endif 94 | time_t day, leap_day, month, year; 95 | 96 | if (!tz_utc) 97 | second -= sys_tz.tz_minuteswest * SECS_PER_MIN; 98 | 99 | if (second < UNIX_SECS_1980) { 100 | tp->sec = 0; 101 | tp->min = 0; 102 | tp->hour = 0; 103 | tp->day = 1; 104 | tp->mon = 1; 105 | tp->year = 0; 106 | return(tp); 107 | } 108 | #if BITS_PER_LONG == 64 109 | if (second >= UNIX_SECS_2108) { 110 | tp->sec = 59; 111 | tp->min = 59; 112 | tp->hour = 23; 113 | tp->day = 31; 114 | tp->mon = 12; 115 | tp->year = 127; 116 | return(tp); 117 | } 118 | #endif 119 | 120 | day = second / SECS_PER_DAY - DAYS_DELTA_DECADE; 121 | year = day / 365; 122 | 123 | MAKE_LEAP_YEAR(leap_day, year); 124 | if (year * 365 + leap_day > day) 125 | year--; 126 | 127 | MAKE_LEAP_YEAR(leap_day, year); 128 | 129 | day -= year * 365 + leap_day; 130 | 131 | if (IS_LEAP_YEAR(year) && day == accum_days_in_year[3]) { 132 | month = 2; 133 | } else { 134 | if (IS_LEAP_YEAR(year) && day > accum_days_in_year[3]) 135 | day--; 136 | for (month = 1; month < 12; month++) { 137 | if (accum_days_in_year[month + 1] > day) 138 | break; 139 | } 140 | } 141 | day -= accum_days_in_year[month]; 142 | 143 | tp->sec = second % SECS_PER_MIN; 144 | tp->min = (second / SECS_PER_MIN) % 60; 145 | tp->hour = (second / SECS_PER_HOUR) % 24; 146 | tp->day = day + 1; 147 | tp->mon = month; 148 | tp->year = year; 149 | 150 | return(tp); 151 | } 152 | -------------------------------------------------------------------------------- /exfat_oal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation; either version 2 7 | * of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | #ifndef _EXFAT_OAL_H 20 | #define _EXFAT_OAL_H 21 | 22 | #include "exfat_global.h" 23 | #include 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | typedef struct { 30 | UINT16 sec; 31 | UINT16 min; 32 | UINT16 hour; 33 | UINT16 day; 34 | UINT16 mon; 35 | UINT16 year; 36 | } TIMESTAMP_T; 37 | 38 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37) 39 | #define DECLARE_MUTEX(m) DEFINE_SEMAPHORE(m) 40 | #endif 41 | 42 | INT32 sm_init(struct semaphore *sm); 43 | INT32 sm_P(struct semaphore *sm); 44 | void sm_V(struct semaphore *sm); 45 | 46 | TIMESTAMP_T *tm_current(TIMESTAMP_T *tm, UINT8 tz_utc); 47 | 48 | #ifdef __cplusplus 49 | } 50 | #endif 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /exfat_part.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation; either version 2 7 | * of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | #ifndef _EXFAT_PART_H 20 | #define _EXFAT_PART_H 21 | 22 | #include "exfat_global.h" 23 | #include "exfat_api.h" 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | #define MBR_SIGNATURE 0xAA55 30 | typedef struct { 31 | UINT8 boot_code[446]; 32 | UINT8 partition[64]; 33 | UINT8 signature[2]; 34 | } MBR_SECTOR_T; 35 | 36 | typedef struct { 37 | UINT8 def_boot; 38 | UINT8 bgn_chs[3]; 39 | UINT8 sys_type; 40 | UINT8 end_chs[3]; 41 | UINT8 start_sector[4]; 42 | UINT8 num_sectors[4]; 43 | } PART_ENTRY_T; 44 | 45 | INT32 ffsSetPartition(INT32 dev, INT32 num_vol, PART_INFO_T *vol_spec); 46 | INT32 ffsGetPartition(INT32 dev, INT32 *num_vol, PART_INFO_T *vol_spec); 47 | INT32 ffsGetDevInfo(INT32 dev, DEV_INFO_T *info); 48 | 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /exfat_super.h: -------------------------------------------------------------------------------- 1 | /* Some of the source code in this file came from "linux/fs/fat/fat.h". */ 2 | 3 | /* 4 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #ifndef _EXFAT_LINUX_H 22 | #define _EXFAT_LINUX_H 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "exfat_global.h" 32 | #include "exfat_data.h" 33 | #include "exfat_oal.h" 34 | 35 | #include "exfat_blkdev.h" 36 | #include "exfat_cache.h" 37 | #include "exfat_part.h" 38 | #include "exfat_nls.h" 39 | #include "exfat_api.h" 40 | #include "exfat.h" 41 | 42 | #define EXFAT_ERRORS_CONT 1 43 | #define EXFAT_ERRORS_PANIC 2 44 | #define EXFAT_ERRORS_RO 3 45 | 46 | #define EXFAT_IOCTL_GET_VOLUME_ID _IOR('r', 0x12, __u32) 47 | 48 | struct exfat_mount_options { 49 | #if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) 50 | uid_t fs_uid; 51 | gid_t fs_gid; 52 | #else 53 | kuid_t fs_uid; 54 | kgid_t fs_gid; 55 | #endif 56 | unsigned short fs_fmask; 57 | unsigned short fs_dmask; 58 | unsigned short allow_utime; 59 | unsigned short codepage; 60 | char *iocharset; 61 | unsigned char casesensitive; 62 | unsigned char tz_utc; 63 | unsigned char discard; 64 | unsigned char errors; 65 | }; 66 | 67 | #define EXFAT_HASH_BITS 8 68 | #define EXFAT_HASH_SIZE (1UL << EXFAT_HASH_BITS) 69 | 70 | struct exfat_sb_info { 71 | FS_INFO_T fs_info; 72 | BD_INFO_T bd_info; 73 | 74 | struct exfat_mount_options options; 75 | int use_vmalloc; 76 | 77 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0) 78 | int s_dirt; 79 | struct mutex s_lock; 80 | #endif 81 | struct nls_table *nls_disk; 82 | struct nls_table *nls_io; 83 | 84 | struct inode *fat_inode; 85 | 86 | spinlock_t inode_hash_lock; 87 | struct hlist_head inode_hashtable[EXFAT_HASH_SIZE]; 88 | #ifdef CONFIG_EXFAT_DEBUG 89 | long debug_flags; 90 | #endif 91 | }; 92 | 93 | struct exfat_inode_info { 94 | FILE_ID_T fid; 95 | char *target; 96 | loff_t mmu_private; 97 | loff_t i_pos; 98 | struct hlist_node i_hash_fat; 99 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0) 100 | struct rw_semaphore truncate_lock; 101 | #endif 102 | struct inode vfs_inode; 103 | }; 104 | 105 | #define EXFAT_SB(sb) ((struct exfat_sb_info *)((sb)->s_fs_info)) 106 | 107 | static inline struct exfat_inode_info *EXFAT_I(struct inode *inode) { 108 | return container_of(inode, struct exfat_inode_info, vfs_inode); 109 | } 110 | 111 | static inline int exfat_mode_can_hold_ro(struct inode *inode) 112 | { 113 | struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb); 114 | 115 | if (S_ISDIR(inode->i_mode)) 116 | return 0; 117 | 118 | if ((~sbi->options.fs_fmask) & S_IWUGO) 119 | return 1; 120 | return 0; 121 | } 122 | 123 | static inline mode_t exfat_make_mode(struct exfat_sb_info *sbi, 124 | u32 attr, mode_t mode) 125 | { 126 | if ((attr & ATTR_READONLY) && !(attr & ATTR_SUBDIR)) 127 | mode &= ~S_IWUGO; 128 | 129 | if (attr & ATTR_SUBDIR) 130 | return (mode & ~sbi->options.fs_dmask) | S_IFDIR; 131 | else if (attr & ATTR_SYMLINK) 132 | return (mode & ~sbi->options.fs_dmask) | S_IFLNK; 133 | else 134 | return (mode & ~sbi->options.fs_fmask) | S_IFREG; 135 | } 136 | 137 | static inline u32 exfat_make_attr(struct inode *inode) 138 | { 139 | if (exfat_mode_can_hold_ro(inode) && !(inode->i_mode & S_IWUGO)) 140 | return ((EXFAT_I(inode)->fid.attr) | ATTR_READONLY); 141 | else 142 | return (EXFAT_I(inode)->fid.attr); 143 | } 144 | 145 | static inline void exfat_save_attr(struct inode *inode, u32 attr) 146 | { 147 | if (exfat_mode_can_hold_ro(inode)) 148 | EXFAT_I(inode)->fid.attr = attr & ATTR_RWMASK; 149 | else 150 | EXFAT_I(inode)->fid.attr = attr & (ATTR_RWMASK | ATTR_READONLY); 151 | } 152 | 153 | /* exfat_xattr.c */ 154 | extern int exfat_setxattr(struct dentry *dentry, const char *name, 155 | const void *value, size_t size, int flags); 156 | extern ssize_t exfat_getxattr(struct dentry *dentry, const char *name, 157 | void *value, size_t size); 158 | extern ssize_t exfat_listxattr(struct dentry *dentry, char *list, size_t size); 159 | extern int exfat_removexattr(struct dentry *dentry, const char *name); 160 | 161 | #endif 162 | -------------------------------------------------------------------------------- /exfat_upcase.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation; either version 2 7 | * of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | #include "exfat_global.h" 20 | 21 | #include "exfat_nls.h" 22 | 23 | const UINT8 uni_upcase[NUM_UPCASE<<1] = { 24 | 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 25 | 0x08, 0x00, 0x09, 0x00, 0x0A, 0x00, 0x0B, 0x00, 0x0C, 0x00, 0x0D, 0x00, 0x0E, 0x00, 0x0F, 0x00, 26 | 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, 27 | 0x18, 0x00, 0x19, 0x00, 0x1A, 0x00, 0x1B, 0x00, 0x1C, 0x00, 0x1D, 0x00, 0x1E, 0x00, 0x1F, 0x00, 28 | 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, 0x00, 29 | 0x28, 0x00, 0x29, 0x00, 0x2A, 0x00, 0x2B, 0x00, 0x2C, 0x00, 0x2D, 0x00, 0x2E, 0x00, 0x2F, 0x00, 30 | 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 31 | 0x38, 0x00, 0x39, 0x00, 0x3A, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3D, 0x00, 0x3E, 0x00, 0x3F, 0x00, 32 | 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 33 | 0x48, 0x00, 0x49, 0x00, 0x4A, 0x00, 0x4B, 0x00, 0x4C, 0x00, 0x4D, 0x00, 0x4E, 0x00, 0x4F, 0x00, 34 | 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, 35 | 0x58, 0x00, 0x59, 0x00, 0x5A, 0x00, 0x5B, 0x00, 0x5C, 0x00, 0x5D, 0x00, 0x5E, 0x00, 0x5F, 0x00, 36 | 0x60, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 37 | 0x48, 0x00, 0x49, 0x00, 0x4A, 0x00, 0x4B, 0x00, 0x4C, 0x00, 0x4D, 0x00, 0x4E, 0x00, 0x4F, 0x00, 38 | 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, 39 | 0x58, 0x00, 0x59, 0x00, 0x5A, 0x00, 0x7B, 0x00, 0x7C, 0x00, 0x7D, 0x00, 0x7E, 0x00, 0x7F, 0x00, 40 | 0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0x85, 0x00, 0x86, 0x00, 0x87, 0x00, 41 | 0x88, 0x00, 0x89, 0x00, 0x8A, 0x00, 0x8B, 0x00, 0x8C, 0x00, 0x8D, 0x00, 0x8E, 0x00, 0x8F, 0x00, 42 | 0x90, 0x00, 0x91, 0x00, 0x92, 0x00, 0x93, 0x00, 0x94, 0x00, 0x95, 0x00, 0x96, 0x00, 0x97, 0x00, 43 | 0x98, 0x00, 0x99, 0x00, 0x9A, 0x00, 0x9B, 0x00, 0x9C, 0x00, 0x9D, 0x00, 0x9E, 0x00, 0x9F, 0x00, 44 | 0xA0, 0x00, 0xA1, 0x00, 0xA2, 0x00, 0xA3, 0x00, 0xA4, 0x00, 0xA5, 0x00, 0xA6, 0x00, 0xA7, 0x00, 45 | 0xA8, 0x00, 0xA9, 0x00, 0xAA, 0x00, 0xAB, 0x00, 0xAC, 0x00, 0xAD, 0x00, 0xAE, 0x00, 0xAF, 0x00, 46 | 0xB0, 0x00, 0xB1, 0x00, 0xB2, 0x00, 0xB3, 0x00, 0xB4, 0x00, 0xB5, 0x00, 0xB6, 0x00, 0xB7, 0x00, 47 | 0xB8, 0x00, 0xB9, 0x00, 0xBA, 0x00, 0xBB, 0x00, 0xBC, 0x00, 0xBD, 0x00, 0xBE, 0x00, 0xBF, 0x00, 48 | 0xC0, 0x00, 0xC1, 0x00, 0xC2, 0x00, 0xC3, 0x00, 0xC4, 0x00, 0xC5, 0x00, 0xC6, 0x00, 0xC7, 0x00, 49 | 0xC8, 0x00, 0xC9, 0x00, 0xCA, 0x00, 0xCB, 0x00, 0xCC, 0x00, 0xCD, 0x00, 0xCE, 0x00, 0xCF, 0x00, 50 | 0xD0, 0x00, 0xD1, 0x00, 0xD2, 0x00, 0xD3, 0x00, 0xD4, 0x00, 0xD5, 0x00, 0xD6, 0x00, 0xD7, 0x00, 51 | 0xD8, 0x00, 0xD9, 0x00, 0xDA, 0x00, 0xDB, 0x00, 0xDC, 0x00, 0xDD, 0x00, 0xDE, 0x00, 0xDF, 0x00, 52 | 0xC0, 0x00, 0xC1, 0x00, 0xC2, 0x00, 0xC3, 0x00, 0xC4, 0x00, 0xC5, 0x00, 0xC6, 0x00, 0xC7, 0x00, 53 | 0xC8, 0x00, 0xC9, 0x00, 0xCA, 0x00, 0xCB, 0x00, 0xCC, 0x00, 0xCD, 0x00, 0xCE, 0x00, 0xCF, 0x00, 54 | 0xD0, 0x00, 0xD1, 0x00, 0xD2, 0x00, 0xD3, 0x00, 0xD4, 0x00, 0xD5, 0x00, 0xD6, 0x00, 0xF7, 0x00, 55 | 0xD8, 0x00, 0xD9, 0x00, 0xDA, 0x00, 0xDB, 0x00, 0xDC, 0x00, 0xDD, 0x00, 0xDE, 0x00, 0x78, 0x01, 56 | 0x00, 0x01, 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x04, 0x01, 0x04, 0x01, 0x06, 0x01, 0x06, 0x01, 57 | 0x08, 0x01, 0x08, 0x01, 0x0A, 0x01, 0x0A, 0x01, 0x0C, 0x01, 0x0C, 0x01, 0x0E, 0x01, 0x0E, 0x01, 58 | 0x10, 0x01, 0x10, 0x01, 0x12, 0x01, 0x12, 0x01, 0x14, 0x01, 0x14, 0x01, 0x16, 0x01, 0x16, 0x01, 59 | 0x18, 0x01, 0x18, 0x01, 0x1A, 0x01, 0x1A, 0x01, 0x1C, 0x01, 0x1C, 0x01, 0x1E, 0x01, 0x1E, 0x01, 60 | 0x20, 0x01, 0x20, 0x01, 0x22, 0x01, 0x22, 0x01, 0x24, 0x01, 0x24, 0x01, 0x26, 0x01, 0x26, 0x01, 61 | 0x28, 0x01, 0x28, 0x01, 0x2A, 0x01, 0x2A, 0x01, 0x2C, 0x01, 0x2C, 0x01, 0x2E, 0x01, 0x2E, 0x01, 62 | 0x30, 0x01, 0x31, 0x01, 0x32, 0x01, 0x32, 0x01, 0x34, 0x01, 0x34, 0x01, 0x36, 0x01, 0x36, 0x01, 63 | 0x38, 0x01, 0x39, 0x01, 0x39, 0x01, 0x3B, 0x01, 0x3B, 0x01, 0x3D, 0x01, 0x3D, 0x01, 0x3F, 0x01, 64 | 0x3F, 0x01, 0x41, 0x01, 0x41, 0x01, 0x43, 0x01, 0x43, 0x01, 0x45, 0x01, 0x45, 0x01, 0x47, 0x01, 65 | 0x47, 0x01, 0x49, 0x01, 0x4A, 0x01, 0x4A, 0x01, 0x4C, 0x01, 0x4C, 0x01, 0x4E, 0x01, 0x4E, 0x01, 66 | 0x50, 0x01, 0x50, 0x01, 0x52, 0x01, 0x52, 0x01, 0x54, 0x01, 0x54, 0x01, 0x56, 0x01, 0x56, 0x01, 67 | 0x58, 0x01, 0x58, 0x01, 0x5A, 0x01, 0x5A, 0x01, 0x5C, 0x01, 0x5C, 0x01, 0x5E, 0x01, 0x5E, 0x01, 68 | 0x60, 0x01, 0x60, 0x01, 0x62, 0x01, 0x62, 0x01, 0x64, 0x01, 0x64, 0x01, 0x66, 0x01, 0x66, 0x01, 69 | 0x68, 0x01, 0x68, 0x01, 0x6A, 0x01, 0x6A, 0x01, 0x6C, 0x01, 0x6C, 0x01, 0x6E, 0x01, 0x6E, 0x01, 70 | 0x70, 0x01, 0x70, 0x01, 0x72, 0x01, 0x72, 0x01, 0x74, 0x01, 0x74, 0x01, 0x76, 0x01, 0x76, 0x01, 71 | 0x78, 0x01, 0x79, 0x01, 0x79, 0x01, 0x7B, 0x01, 0x7B, 0x01, 0x7D, 0x01, 0x7D, 0x01, 0x7F, 0x01, 72 | 0x43, 0x02, 0x81, 0x01, 0x82, 0x01, 0x82, 0x01, 0x84, 0x01, 0x84, 0x01, 0x86, 0x01, 0x87, 0x01, 73 | 0x87, 0x01, 0x89, 0x01, 0x8A, 0x01, 0x8B, 0x01, 0x8B, 0x01, 0x8D, 0x01, 0x8E, 0x01, 0x8F, 0x01, 74 | 0x90, 0x01, 0x91, 0x01, 0x91, 0x01, 0x93, 0x01, 0x94, 0x01, 0xF6, 0x01, 0x96, 0x01, 0x97, 0x01, 75 | 0x98, 0x01, 0x98, 0x01, 0x3D, 0x02, 0x9B, 0x01, 0x9C, 0x01, 0x9D, 0x01, 0x20, 0x02, 0x9F, 0x01, 76 | 0xA0, 0x01, 0xA0, 0x01, 0xA2, 0x01, 0xA2, 0x01, 0xA4, 0x01, 0xA4, 0x01, 0xA6, 0x01, 0xA7, 0x01, 77 | 0xA7, 0x01, 0xA9, 0x01, 0xAA, 0x01, 0xAB, 0x01, 0xAC, 0x01, 0xAC, 0x01, 0xAE, 0x01, 0xAF, 0x01, 78 | 0xAF, 0x01, 0xB1, 0x01, 0xB2, 0x01, 0xB3, 0x01, 0xB3, 0x01, 0xB5, 0x01, 0xB5, 0x01, 0xB7, 0x01, 79 | 0xB8, 0x01, 0xB8, 0x01, 0xBA, 0x01, 0xBB, 0x01, 0xBC, 0x01, 0xBC, 0x01, 0xBE, 0x01, 0xF7, 0x01, 80 | 0xC0, 0x01, 0xC1, 0x01, 0xC2, 0x01, 0xC3, 0x01, 0xC4, 0x01, 0xC5, 0x01, 0xC4, 0x01, 0xC7, 0x01, 81 | 0xC8, 0x01, 0xC7, 0x01, 0xCA, 0x01, 0xCB, 0x01, 0xCA, 0x01, 0xCD, 0x01, 0xCD, 0x01, 0xCF, 0x01, 82 | 0xCF, 0x01, 0xD1, 0x01, 0xD1, 0x01, 0xD3, 0x01, 0xD3, 0x01, 0xD5, 0x01, 0xD5, 0x01, 0xD7, 0x01, 83 | 0xD7, 0x01, 0xD9, 0x01, 0xD9, 0x01, 0xDB, 0x01, 0xDB, 0x01, 0x8E, 0x01, 0xDE, 0x01, 0xDE, 0x01, 84 | 0xE0, 0x01, 0xE0, 0x01, 0xE2, 0x01, 0xE2, 0x01, 0xE4, 0x01, 0xE4, 0x01, 0xE6, 0x01, 0xE6, 0x01, 85 | 0xE8, 0x01, 0xE8, 0x01, 0xEA, 0x01, 0xEA, 0x01, 0xEC, 0x01, 0xEC, 0x01, 0xEE, 0x01, 0xEE, 0x01, 86 | 0xF0, 0x01, 0xF1, 0x01, 0xF2, 0x01, 0xF1, 0x01, 0xF4, 0x01, 0xF4, 0x01, 0xF6, 0x01, 0xF7, 0x01, 87 | 0xF8, 0x01, 0xF8, 0x01, 0xFA, 0x01, 0xFA, 0x01, 0xFC, 0x01, 0xFC, 0x01, 0xFE, 0x01, 0xFE, 0x01, 88 | 0x00, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x02, 0x04, 0x02, 0x06, 0x02, 0x06, 0x02, 89 | 0x08, 0x02, 0x08, 0x02, 0x0A, 0x02, 0x0A, 0x02, 0x0C, 0x02, 0x0C, 0x02, 0x0E, 0x02, 0x0E, 0x02, 90 | 0x10, 0x02, 0x10, 0x02, 0x12, 0x02, 0x12, 0x02, 0x14, 0x02, 0x14, 0x02, 0x16, 0x02, 0x16, 0x02, 91 | 0x18, 0x02, 0x18, 0x02, 0x1A, 0x02, 0x1A, 0x02, 0x1C, 0x02, 0x1C, 0x02, 0x1E, 0x02, 0x1E, 0x02, 92 | 0x20, 0x02, 0x21, 0x02, 0x22, 0x02, 0x22, 0x02, 0x24, 0x02, 0x24, 0x02, 0x26, 0x02, 0x26, 0x02, 93 | 0x28, 0x02, 0x28, 0x02, 0x2A, 0x02, 0x2A, 0x02, 0x2C, 0x02, 0x2C, 0x02, 0x2E, 0x02, 0x2E, 0x02, 94 | 0x30, 0x02, 0x30, 0x02, 0x32, 0x02, 0x32, 0x02, 0x34, 0x02, 0x35, 0x02, 0x36, 0x02, 0x37, 0x02, 95 | 0x38, 0x02, 0x39, 0x02, 0x65, 0x2C, 0x3B, 0x02, 0x3B, 0x02, 0x3D, 0x02, 0x66, 0x2C, 0x3F, 0x02, 96 | 0x40, 0x02, 0x41, 0x02, 0x41, 0x02, 0x43, 0x02, 0x44, 0x02, 0x45, 0x02, 0x46, 0x02, 0x46, 0x02, 97 | 0x48, 0x02, 0x48, 0x02, 0x4A, 0x02, 0x4A, 0x02, 0x4C, 0x02, 0x4C, 0x02, 0x4E, 0x02, 0x4E, 0x02, 98 | 0x50, 0x02, 0x51, 0x02, 0x52, 0x02, 0x81, 0x01, 0x86, 0x01, 0x55, 0x02, 0x89, 0x01, 0x8A, 0x01, 99 | 0x58, 0x02, 0x8F, 0x01, 0x5A, 0x02, 0x90, 0x01, 0x5C, 0x02, 0x5D, 0x02, 0x5E, 0x02, 0x5F, 0x02, 100 | 0x93, 0x01, 0x61, 0x02, 0x62, 0x02, 0x94, 0x01, 0x64, 0x02, 0x65, 0x02, 0x66, 0x02, 0x67, 0x02, 101 | 0x97, 0x01, 0x96, 0x01, 0x6A, 0x02, 0x62, 0x2C, 0x6C, 0x02, 0x6D, 0x02, 0x6E, 0x02, 0x9C, 0x01, 102 | 0x70, 0x02, 0x71, 0x02, 0x9D, 0x01, 0x73, 0x02, 0x74, 0x02, 0x9F, 0x01, 0x76, 0x02, 0x77, 0x02, 103 | 0x78, 0x02, 0x79, 0x02, 0x7A, 0x02, 0x7B, 0x02, 0x7C, 0x02, 0x64, 0x2C, 0x7E, 0x02, 0x7F, 0x02, 104 | 0xA6, 0x01, 0x81, 0x02, 0x82, 0x02, 0xA9, 0x01, 0x84, 0x02, 0x85, 0x02, 0x86, 0x02, 0x87, 0x02, 105 | 0xAE, 0x01, 0x44, 0x02, 0xB1, 0x01, 0xB2, 0x01, 0x45, 0x02, 0x8D, 0x02, 0x8E, 0x02, 0x8F, 0x02, 106 | 0x90, 0x02, 0x91, 0x02, 0xB7, 0x01, 0x93, 0x02, 0x94, 0x02, 0x95, 0x02, 0x96, 0x02, 0x97, 0x02, 107 | 0x98, 0x02, 0x99, 0x02, 0x9A, 0x02, 0x9B, 0x02, 0x9C, 0x02, 0x9D, 0x02, 0x9E, 0x02, 0x9F, 0x02, 108 | 0xA0, 0x02, 0xA1, 0x02, 0xA2, 0x02, 0xA3, 0x02, 0xA4, 0x02, 0xA5, 0x02, 0xA6, 0x02, 0xA7, 0x02, 109 | 0xA8, 0x02, 0xA9, 0x02, 0xAA, 0x02, 0xAB, 0x02, 0xAC, 0x02, 0xAD, 0x02, 0xAE, 0x02, 0xAF, 0x02, 110 | 0xB0, 0x02, 0xB1, 0x02, 0xB2, 0x02, 0xB3, 0x02, 0xB4, 0x02, 0xB5, 0x02, 0xB6, 0x02, 0xB7, 0x02, 111 | 0xB8, 0x02, 0xB9, 0x02, 0xBA, 0x02, 0xBB, 0x02, 0xBC, 0x02, 0xBD, 0x02, 0xBE, 0x02, 0xBF, 0x02, 112 | 0xC0, 0x02, 0xC1, 0x02, 0xC2, 0x02, 0xC3, 0x02, 0xC4, 0x02, 0xC5, 0x02, 0xC6, 0x02, 0xC7, 0x02, 113 | 0xC8, 0x02, 0xC9, 0x02, 0xCA, 0x02, 0xCB, 0x02, 0xCC, 0x02, 0xCD, 0x02, 0xCE, 0x02, 0xCF, 0x02, 114 | 0xD0, 0x02, 0xD1, 0x02, 0xD2, 0x02, 0xD3, 0x02, 0xD4, 0x02, 0xD5, 0x02, 0xD6, 0x02, 0xD7, 0x02, 115 | 0xD8, 0x02, 0xD9, 0x02, 0xDA, 0x02, 0xDB, 0x02, 0xDC, 0x02, 0xDD, 0x02, 0xDE, 0x02, 0xDF, 0x02, 116 | 0xE0, 0x02, 0xE1, 0x02, 0xE2, 0x02, 0xE3, 0x02, 0xE4, 0x02, 0xE5, 0x02, 0xE6, 0x02, 0xE7, 0x02, 117 | 0xE8, 0x02, 0xE9, 0x02, 0xEA, 0x02, 0xEB, 0x02, 0xEC, 0x02, 0xED, 0x02, 0xEE, 0x02, 0xEF, 0x02, 118 | 0xF0, 0x02, 0xF1, 0x02, 0xF2, 0x02, 0xF3, 0x02, 0xF4, 0x02, 0xF5, 0x02, 0xF6, 0x02, 0xF7, 0x02, 119 | 0xF8, 0x02, 0xF9, 0x02, 0xFA, 0x02, 0xFB, 0x02, 0xFC, 0x02, 0xFD, 0x02, 0xFE, 0x02, 0xFF, 0x02, 120 | 0x00, 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, 0x03, 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x07, 0x03, 121 | 0x08, 0x03, 0x09, 0x03, 0x0A, 0x03, 0x0B, 0x03, 0x0C, 0x03, 0x0D, 0x03, 0x0E, 0x03, 0x0F, 0x03, 122 | 0x10, 0x03, 0x11, 0x03, 0x12, 0x03, 0x13, 0x03, 0x14, 0x03, 0x15, 0x03, 0x16, 0x03, 0x17, 0x03, 123 | 0x18, 0x03, 0x19, 0x03, 0x1A, 0x03, 0x1B, 0x03, 0x1C, 0x03, 0x1D, 0x03, 0x1E, 0x03, 0x1F, 0x03, 124 | 0x20, 0x03, 0x21, 0x03, 0x22, 0x03, 0x23, 0x03, 0x24, 0x03, 0x25, 0x03, 0x26, 0x03, 0x27, 0x03, 125 | 0x28, 0x03, 0x29, 0x03, 0x2A, 0x03, 0x2B, 0x03, 0x2C, 0x03, 0x2D, 0x03, 0x2E, 0x03, 0x2F, 0x03, 126 | 0x30, 0x03, 0x31, 0x03, 0x32, 0x03, 0x33, 0x03, 0x34, 0x03, 0x35, 0x03, 0x36, 0x03, 0x37, 0x03, 127 | 0x38, 0x03, 0x39, 0x03, 0x3A, 0x03, 0x3B, 0x03, 0x3C, 0x03, 0x3D, 0x03, 0x3E, 0x03, 0x3F, 0x03, 128 | 0x40, 0x03, 0x41, 0x03, 0x42, 0x03, 0x43, 0x03, 0x44, 0x03, 0x45, 0x03, 0x46, 0x03, 0x47, 0x03, 129 | 0x48, 0x03, 0x49, 0x03, 0x4A, 0x03, 0x4B, 0x03, 0x4C, 0x03, 0x4D, 0x03, 0x4E, 0x03, 0x4F, 0x03, 130 | 0x50, 0x03, 0x51, 0x03, 0x52, 0x03, 0x53, 0x03, 0x54, 0x03, 0x55, 0x03, 0x56, 0x03, 0x57, 0x03, 131 | 0x58, 0x03, 0x59, 0x03, 0x5A, 0x03, 0x5B, 0x03, 0x5C, 0x03, 0x5D, 0x03, 0x5E, 0x03, 0x5F, 0x03, 132 | 0x60, 0x03, 0x61, 0x03, 0x62, 0x03, 0x63, 0x03, 0x64, 0x03, 0x65, 0x03, 0x66, 0x03, 0x67, 0x03, 133 | 0x68, 0x03, 0x69, 0x03, 0x6A, 0x03, 0x6B, 0x03, 0x6C, 0x03, 0x6D, 0x03, 0x6E, 0x03, 0x6F, 0x03, 134 | 0x70, 0x03, 0x71, 0x03, 0x72, 0x03, 0x73, 0x03, 0x74, 0x03, 0x75, 0x03, 0x76, 0x03, 0x77, 0x03, 135 | 0x78, 0x03, 0x79, 0x03, 0x7A, 0x03, 0xFD, 0x03, 0xFE, 0x03, 0xFF, 0x03, 0x7E, 0x03, 0x7F, 0x03, 136 | 0x80, 0x03, 0x81, 0x03, 0x82, 0x03, 0x83, 0x03, 0x84, 0x03, 0x85, 0x03, 0x86, 0x03, 0x87, 0x03, 137 | 0x88, 0x03, 0x89, 0x03, 0x8A, 0x03, 0x8B, 0x03, 0x8C, 0x03, 0x8D, 0x03, 0x8E, 0x03, 0x8F, 0x03, 138 | 0x90, 0x03, 0x91, 0x03, 0x92, 0x03, 0x93, 0x03, 0x94, 0x03, 0x95, 0x03, 0x96, 0x03, 0x97, 0x03, 139 | 0x98, 0x03, 0x99, 0x03, 0x9A, 0x03, 0x9B, 0x03, 0x9C, 0x03, 0x9D, 0x03, 0x9E, 0x03, 0x9F, 0x03, 140 | 0xA0, 0x03, 0xA1, 0x03, 0xA2, 0x03, 0xA3, 0x03, 0xA4, 0x03, 0xA5, 0x03, 0xA6, 0x03, 0xA7, 0x03, 141 | 0xA8, 0x03, 0xA9, 0x03, 0xAA, 0x03, 0xAB, 0x03, 0x86, 0x03, 0x88, 0x03, 0x89, 0x03, 0x8A, 0x03, 142 | 0xB0, 0x03, 0x91, 0x03, 0x92, 0x03, 0x93, 0x03, 0x94, 0x03, 0x95, 0x03, 0x96, 0x03, 0x97, 0x03, 143 | 0x98, 0x03, 0x99, 0x03, 0x9A, 0x03, 0x9B, 0x03, 0x9C, 0x03, 0x9D, 0x03, 0x9E, 0x03, 0x9F, 0x03, 144 | 0xA0, 0x03, 0xA1, 0x03, 0xA3, 0x03, 0xA3, 0x03, 0xA4, 0x03, 0xA5, 0x03, 0xA6, 0x03, 0xA7, 0x03, 145 | 0xA8, 0x03, 0xA9, 0x03, 0xAA, 0x03, 0xAB, 0x03, 0x8C, 0x03, 0x8E, 0x03, 0x8F, 0x03, 0xCF, 0x03, 146 | 0xD0, 0x03, 0xD1, 0x03, 0xD2, 0x03, 0xD3, 0x03, 0xD4, 0x03, 0xD5, 0x03, 0xD6, 0x03, 0xD7, 0x03, 147 | 0xD8, 0x03, 0xD8, 0x03, 0xDA, 0x03, 0xDA, 0x03, 0xDC, 0x03, 0xDC, 0x03, 0xDE, 0x03, 0xDE, 0x03, 148 | 0xE0, 0x03, 0xE0, 0x03, 0xE2, 0x03, 0xE2, 0x03, 0xE4, 0x03, 0xE4, 0x03, 0xE6, 0x03, 0xE6, 0x03, 149 | 0xE8, 0x03, 0xE8, 0x03, 0xEA, 0x03, 0xEA, 0x03, 0xEC, 0x03, 0xEC, 0x03, 0xEE, 0x03, 0xEE, 0x03, 150 | 0xF0, 0x03, 0xF1, 0x03, 0xF9, 0x03, 0xF3, 0x03, 0xF4, 0x03, 0xF5, 0x03, 0xF6, 0x03, 0xF7, 0x03, 151 | 0xF7, 0x03, 0xF9, 0x03, 0xFA, 0x03, 0xFA, 0x03, 0xFC, 0x03, 0xFD, 0x03, 0xFE, 0x03, 0xFF, 0x03, 152 | 0x00, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x04, 0x04, 0x04, 0x05, 0x04, 0x06, 0x04, 0x07, 0x04, 153 | 0x08, 0x04, 0x09, 0x04, 0x0A, 0x04, 0x0B, 0x04, 0x0C, 0x04, 0x0D, 0x04, 0x0E, 0x04, 0x0F, 0x04, 154 | 0x10, 0x04, 0x11, 0x04, 0x12, 0x04, 0x13, 0x04, 0x14, 0x04, 0x15, 0x04, 0x16, 0x04, 0x17, 0x04, 155 | 0x18, 0x04, 0x19, 0x04, 0x1A, 0x04, 0x1B, 0x04, 0x1C, 0x04, 0x1D, 0x04, 0x1E, 0x04, 0x1F, 0x04, 156 | 0x20, 0x04, 0x21, 0x04, 0x22, 0x04, 0x23, 0x04, 0x24, 0x04, 0x25, 0x04, 0x26, 0x04, 0x27, 0x04, 157 | 0x28, 0x04, 0x29, 0x04, 0x2A, 0x04, 0x2B, 0x04, 0x2C, 0x04, 0x2D, 0x04, 0x2E, 0x04, 0x2F, 0x04, 158 | 0x10, 0x04, 0x11, 0x04, 0x12, 0x04, 0x13, 0x04, 0x14, 0x04, 0x15, 0x04, 0x16, 0x04, 0x17, 0x04, 159 | 0x18, 0x04, 0x19, 0x04, 0x1A, 0x04, 0x1B, 0x04, 0x1C, 0x04, 0x1D, 0x04, 0x1E, 0x04, 0x1F, 0x04, 160 | 0x20, 0x04, 0x21, 0x04, 0x22, 0x04, 0x23, 0x04, 0x24, 0x04, 0x25, 0x04, 0x26, 0x04, 0x27, 0x04, 161 | 0x28, 0x04, 0x29, 0x04, 0x2A, 0x04, 0x2B, 0x04, 0x2C, 0x04, 0x2D, 0x04, 0x2E, 0x04, 0x2F, 0x04, 162 | 0x00, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x04, 0x04, 0x04, 0x05, 0x04, 0x06, 0x04, 0x07, 0x04, 163 | 0x08, 0x04, 0x09, 0x04, 0x0A, 0x04, 0x0B, 0x04, 0x0C, 0x04, 0x0D, 0x04, 0x0E, 0x04, 0x0F, 0x04, 164 | 0x60, 0x04, 0x60, 0x04, 0x62, 0x04, 0x62, 0x04, 0x64, 0x04, 0x64, 0x04, 0x66, 0x04, 0x66, 0x04, 165 | 0x68, 0x04, 0x68, 0x04, 0x6A, 0x04, 0x6A, 0x04, 0x6C, 0x04, 0x6C, 0x04, 0x6E, 0x04, 0x6E, 0x04, 166 | 0x70, 0x04, 0x70, 0x04, 0x72, 0x04, 0x72, 0x04, 0x74, 0x04, 0x74, 0x04, 0x76, 0x04, 0x76, 0x04, 167 | 0x78, 0x04, 0x78, 0x04, 0x7A, 0x04, 0x7A, 0x04, 0x7C, 0x04, 0x7C, 0x04, 0x7E, 0x04, 0x7E, 0x04, 168 | 0x80, 0x04, 0x80, 0x04, 0x82, 0x04, 0x83, 0x04, 0x84, 0x04, 0x85, 0x04, 0x86, 0x04, 0x87, 0x04, 169 | 0x88, 0x04, 0x89, 0x04, 0x8A, 0x04, 0x8A, 0x04, 0x8C, 0x04, 0x8C, 0x04, 0x8E, 0x04, 0x8E, 0x04, 170 | 0x90, 0x04, 0x90, 0x04, 0x92, 0x04, 0x92, 0x04, 0x94, 0x04, 0x94, 0x04, 0x96, 0x04, 0x96, 0x04, 171 | 0x98, 0x04, 0x98, 0x04, 0x9A, 0x04, 0x9A, 0x04, 0x9C, 0x04, 0x9C, 0x04, 0x9E, 0x04, 0x9E, 0x04, 172 | 0xA0, 0x04, 0xA0, 0x04, 0xA2, 0x04, 0xA2, 0x04, 0xA4, 0x04, 0xA4, 0x04, 0xA6, 0x04, 0xA6, 0x04, 173 | 0xA8, 0x04, 0xA8, 0x04, 0xAA, 0x04, 0xAA, 0x04, 0xAC, 0x04, 0xAC, 0x04, 0xAE, 0x04, 0xAE, 0x04, 174 | 0xB0, 0x04, 0xB0, 0x04, 0xB2, 0x04, 0xB2, 0x04, 0xB4, 0x04, 0xB4, 0x04, 0xB6, 0x04, 0xB6, 0x04, 175 | 0xB8, 0x04, 0xB8, 0x04, 0xBA, 0x04, 0xBA, 0x04, 0xBC, 0x04, 0xBC, 0x04, 0xBE, 0x04, 0xBE, 0x04, 176 | 0xC0, 0x04, 0xC1, 0x04, 0xC1, 0x04, 0xC3, 0x04, 0xC3, 0x04, 0xC5, 0x04, 0xC5, 0x04, 0xC7, 0x04, 177 | 0xC7, 0x04, 0xC9, 0x04, 0xC9, 0x04, 0xCB, 0x04, 0xCB, 0x04, 0xCD, 0x04, 0xCD, 0x04, 0xC0, 0x04, 178 | 0xD0, 0x04, 0xD0, 0x04, 0xD2, 0x04, 0xD2, 0x04, 0xD4, 0x04, 0xD4, 0x04, 0xD6, 0x04, 0xD6, 0x04, 179 | 0xD8, 0x04, 0xD8, 0x04, 0xDA, 0x04, 0xDA, 0x04, 0xDC, 0x04, 0xDC, 0x04, 0xDE, 0x04, 0xDE, 0x04, 180 | 0xE0, 0x04, 0xE0, 0x04, 0xE2, 0x04, 0xE2, 0x04, 0xE4, 0x04, 0xE4, 0x04, 0xE6, 0x04, 0xE6, 0x04, 181 | 0xE8, 0x04, 0xE8, 0x04, 0xEA, 0x04, 0xEA, 0x04, 0xEC, 0x04, 0xEC, 0x04, 0xEE, 0x04, 0xEE, 0x04, 182 | 0xF0, 0x04, 0xF0, 0x04, 0xF2, 0x04, 0xF2, 0x04, 0xF4, 0x04, 0xF4, 0x04, 0xF6, 0x04, 0xF6, 0x04, 183 | 0xF8, 0x04, 0xF8, 0x04, 0xFA, 0x04, 0xFA, 0x04, 0xFC, 0x04, 0xFC, 0x04, 0xFE, 0x04, 0xFE, 0x04, 184 | 0x00, 0x05, 0x00, 0x05, 0x02, 0x05, 0x02, 0x05, 0x04, 0x05, 0x04, 0x05, 0x06, 0x05, 0x06, 0x05, 185 | 0x08, 0x05, 0x08, 0x05, 0x0A, 0x05, 0x0A, 0x05, 0x0C, 0x05, 0x0C, 0x05, 0x0E, 0x05, 0x0E, 0x05, 186 | 0x10, 0x05, 0x10, 0x05, 0x12, 0x05, 0x12, 0x05, 0x14, 0x05, 0x15, 0x05, 0x16, 0x05, 0x17, 0x05, 187 | 0x18, 0x05, 0x19, 0x05, 0x1A, 0x05, 0x1B, 0x05, 0x1C, 0x05, 0x1D, 0x05, 0x1E, 0x05, 0x1F, 0x05, 188 | 0x20, 0x05, 0x21, 0x05, 0x22, 0x05, 0x23, 0x05, 0x24, 0x05, 0x25, 0x05, 0x26, 0x05, 0x27, 0x05, 189 | 0x28, 0x05, 0x29, 0x05, 0x2A, 0x05, 0x2B, 0x05, 0x2C, 0x05, 0x2D, 0x05, 0x2E, 0x05, 0x2F, 0x05, 190 | 0x30, 0x05, 0x31, 0x05, 0x32, 0x05, 0x33, 0x05, 0x34, 0x05, 0x35, 0x05, 0x36, 0x05, 0x37, 0x05, 191 | 0x38, 0x05, 0x39, 0x05, 0x3A, 0x05, 0x3B, 0x05, 0x3C, 0x05, 0x3D, 0x05, 0x3E, 0x05, 0x3F, 0x05, 192 | 0x40, 0x05, 0x41, 0x05, 0x42, 0x05, 0x43, 0x05, 0x44, 0x05, 0x45, 0x05, 0x46, 0x05, 0x47, 0x05, 193 | 0x48, 0x05, 0x49, 0x05, 0x4A, 0x05, 0x4B, 0x05, 0x4C, 0x05, 0x4D, 0x05, 0x4E, 0x05, 0x4F, 0x05, 194 | 0x50, 0x05, 0x51, 0x05, 0x52, 0x05, 0x53, 0x05, 0x54, 0x05, 0x55, 0x05, 0x56, 0x05, 0x57, 0x05, 195 | 0x58, 0x05, 0x59, 0x05, 0x5A, 0x05, 0x5B, 0x05, 0x5C, 0x05, 0x5D, 0x05, 0x5E, 0x05, 0x5F, 0x05, 196 | 0x60, 0x05, 0x31, 0x05, 0x32, 0x05, 0x33, 0x05, 0x34, 0x05, 0x35, 0x05, 0x36, 0x05, 0x37, 0x05, 197 | 0x38, 0x05, 0x39, 0x05, 0x3A, 0x05, 0x3B, 0x05, 0x3C, 0x05, 0x3D, 0x05, 0x3E, 0x05, 0x3F, 0x05, 198 | 0x40, 0x05, 0x41, 0x05, 0x42, 0x05, 0x43, 0x05, 0x44, 0x05, 0x45, 0x05, 0x46, 0x05, 0x47, 0x05, 199 | 0x48, 0x05, 0x49, 0x05, 0x4A, 0x05, 0x4B, 0x05, 0x4C, 0x05, 0x4D, 0x05, 0x4E, 0x05, 0x4F, 0x05, 200 | 0x50, 0x05, 0x51, 0x05, 0x52, 0x05, 0x53, 0x05, 0x54, 0x05, 0x55, 0x05, 0x56, 0x05, 0xFF, 0xFF, 201 | 0xF6, 0x17, 0x63, 0x2C, 0x7E, 0x1D, 0x7F, 0x1D, 0x80, 0x1D, 0x81, 0x1D, 0x82, 0x1D, 0x83, 0x1D, 202 | 0x84, 0x1D, 0x85, 0x1D, 0x86, 0x1D, 0x87, 0x1D, 0x88, 0x1D, 0x89, 0x1D, 0x8A, 0x1D, 0x8B, 0x1D, 203 | 0x8C, 0x1D, 0x8D, 0x1D, 0x8E, 0x1D, 0x8F, 0x1D, 0x90, 0x1D, 0x91, 0x1D, 0x92, 0x1D, 0x93, 0x1D, 204 | 0x94, 0x1D, 0x95, 0x1D, 0x96, 0x1D, 0x97, 0x1D, 0x98, 0x1D, 0x99, 0x1D, 0x9A, 0x1D, 0x9B, 0x1D, 205 | 0x9C, 0x1D, 0x9D, 0x1D, 0x9E, 0x1D, 0x9F, 0x1D, 0xA0, 0x1D, 0xA1, 0x1D, 0xA2, 0x1D, 0xA3, 0x1D, 206 | 0xA4, 0x1D, 0xA5, 0x1D, 0xA6, 0x1D, 0xA7, 0x1D, 0xA8, 0x1D, 0xA9, 0x1D, 0xAA, 0x1D, 0xAB, 0x1D, 207 | 0xAC, 0x1D, 0xAD, 0x1D, 0xAE, 0x1D, 0xAF, 0x1D, 0xB0, 0x1D, 0xB1, 0x1D, 0xB2, 0x1D, 0xB3, 0x1D, 208 | 0xB4, 0x1D, 0xB5, 0x1D, 0xB6, 0x1D, 0xB7, 0x1D, 0xB8, 0x1D, 0xB9, 0x1D, 0xBA, 0x1D, 0xBB, 0x1D, 209 | 0xBC, 0x1D, 0xBD, 0x1D, 0xBE, 0x1D, 0xBF, 0x1D, 0xC0, 0x1D, 0xC1, 0x1D, 0xC2, 0x1D, 0xC3, 0x1D, 210 | 0xC4, 0x1D, 0xC5, 0x1D, 0xC6, 0x1D, 0xC7, 0x1D, 0xC8, 0x1D, 0xC9, 0x1D, 0xCA, 0x1D, 0xCB, 0x1D, 211 | 0xCC, 0x1D, 0xCD, 0x1D, 0xCE, 0x1D, 0xCF, 0x1D, 0xD0, 0x1D, 0xD1, 0x1D, 0xD2, 0x1D, 0xD3, 0x1D, 212 | 0xD4, 0x1D, 0xD5, 0x1D, 0xD6, 0x1D, 0xD7, 0x1D, 0xD8, 0x1D, 0xD9, 0x1D, 0xDA, 0x1D, 0xDB, 0x1D, 213 | 0xDC, 0x1D, 0xDD, 0x1D, 0xDE, 0x1D, 0xDF, 0x1D, 0xE0, 0x1D, 0xE1, 0x1D, 0xE2, 0x1D, 0xE3, 0x1D, 214 | 0xE4, 0x1D, 0xE5, 0x1D, 0xE6, 0x1D, 0xE7, 0x1D, 0xE8, 0x1D, 0xE9, 0x1D, 0xEA, 0x1D, 0xEB, 0x1D, 215 | 0xEC, 0x1D, 0xED, 0x1D, 0xEE, 0x1D, 0xEF, 0x1D, 0xF0, 0x1D, 0xF1, 0x1D, 0xF2, 0x1D, 0xF3, 0x1D, 216 | 0xF4, 0x1D, 0xF5, 0x1D, 0xF6, 0x1D, 0xF7, 0x1D, 0xF8, 0x1D, 0xF9, 0x1D, 0xFA, 0x1D, 0xFB, 0x1D, 217 | 0xFC, 0x1D, 0xFD, 0x1D, 0xFE, 0x1D, 0xFF, 0x1D, 0x00, 0x1E, 0x00, 0x1E, 0x02, 0x1E, 0x02, 0x1E, 218 | 0x04, 0x1E, 0x04, 0x1E, 0x06, 0x1E, 0x06, 0x1E, 0x08, 0x1E, 0x08, 0x1E, 0x0A, 0x1E, 0x0A, 0x1E, 219 | 0x0C, 0x1E, 0x0C, 0x1E, 0x0E, 0x1E, 0x0E, 0x1E, 0x10, 0x1E, 0x10, 0x1E, 0x12, 0x1E, 0x12, 0x1E, 220 | 0x14, 0x1E, 0x14, 0x1E, 0x16, 0x1E, 0x16, 0x1E, 0x18, 0x1E, 0x18, 0x1E, 0x1A, 0x1E, 0x1A, 0x1E, 221 | 0x1C, 0x1E, 0x1C, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x20, 0x1E, 0x20, 0x1E, 0x22, 0x1E, 0x22, 0x1E, 222 | 0x24, 0x1E, 0x24, 0x1E, 0x26, 0x1E, 0x26, 0x1E, 0x28, 0x1E, 0x28, 0x1E, 0x2A, 0x1E, 0x2A, 0x1E, 223 | 0x2C, 0x1E, 0x2C, 0x1E, 0x2E, 0x1E, 0x2E, 0x1E, 0x30, 0x1E, 0x30, 0x1E, 0x32, 0x1E, 0x32, 0x1E, 224 | 0x34, 0x1E, 0x34, 0x1E, 0x36, 0x1E, 0x36, 0x1E, 0x38, 0x1E, 0x38, 0x1E, 0x3A, 0x1E, 0x3A, 0x1E, 225 | 0x3C, 0x1E, 0x3C, 0x1E, 0x3E, 0x1E, 0x3E, 0x1E, 0x40, 0x1E, 0x40, 0x1E, 0x42, 0x1E, 0x42, 0x1E, 226 | 0x44, 0x1E, 0x44, 0x1E, 0x46, 0x1E, 0x46, 0x1E, 0x48, 0x1E, 0x48, 0x1E, 0x4A, 0x1E, 0x4A, 0x1E, 227 | 0x4C, 0x1E, 0x4C, 0x1E, 0x4E, 0x1E, 0x4E, 0x1E, 0x50, 0x1E, 0x50, 0x1E, 0x52, 0x1E, 0x52, 0x1E, 228 | 0x54, 0x1E, 0x54, 0x1E, 0x56, 0x1E, 0x56, 0x1E, 0x58, 0x1E, 0x58, 0x1E, 0x5A, 0x1E, 0x5A, 0x1E, 229 | 0x5C, 0x1E, 0x5C, 0x1E, 0x5E, 0x1E, 0x5E, 0x1E, 0x60, 0x1E, 0x60, 0x1E, 0x62, 0x1E, 0x62, 0x1E, 230 | 0x64, 0x1E, 0x64, 0x1E, 0x66, 0x1E, 0x66, 0x1E, 0x68, 0x1E, 0x68, 0x1E, 0x6A, 0x1E, 0x6A, 0x1E, 231 | 0x6C, 0x1E, 0x6C, 0x1E, 0x6E, 0x1E, 0x6E, 0x1E, 0x70, 0x1E, 0x70, 0x1E, 0x72, 0x1E, 0x72, 0x1E, 232 | 0x74, 0x1E, 0x74, 0x1E, 0x76, 0x1E, 0x76, 0x1E, 0x78, 0x1E, 0x78, 0x1E, 0x7A, 0x1E, 0x7A, 0x1E, 233 | 0x7C, 0x1E, 0x7C, 0x1E, 0x7E, 0x1E, 0x7E, 0x1E, 0x80, 0x1E, 0x80, 0x1E, 0x82, 0x1E, 0x82, 0x1E, 234 | 0x84, 0x1E, 0x84, 0x1E, 0x86, 0x1E, 0x86, 0x1E, 0x88, 0x1E, 0x88, 0x1E, 0x8A, 0x1E, 0x8A, 0x1E, 235 | 0x8C, 0x1E, 0x8C, 0x1E, 0x8E, 0x1E, 0x8E, 0x1E, 0x90, 0x1E, 0x90, 0x1E, 0x92, 0x1E, 0x92, 0x1E, 236 | 0x94, 0x1E, 0x94, 0x1E, 0x96, 0x1E, 0x97, 0x1E, 0x98, 0x1E, 0x99, 0x1E, 0x9A, 0x1E, 0x9B, 0x1E, 237 | 0x9C, 0x1E, 0x9D, 0x1E, 0x9E, 0x1E, 0x9F, 0x1E, 0xA0, 0x1E, 0xA0, 0x1E, 0xA2, 0x1E, 0xA2, 0x1E, 238 | 0xA4, 0x1E, 0xA4, 0x1E, 0xA6, 0x1E, 0xA6, 0x1E, 0xA8, 0x1E, 0xA8, 0x1E, 0xAA, 0x1E, 0xAA, 0x1E, 239 | 0xAC, 0x1E, 0xAC, 0x1E, 0xAE, 0x1E, 0xAE, 0x1E, 0xB0, 0x1E, 0xB0, 0x1E, 0xB2, 0x1E, 0xB2, 0x1E, 240 | 0xB4, 0x1E, 0xB4, 0x1E, 0xB6, 0x1E, 0xB6, 0x1E, 0xB8, 0x1E, 0xB8, 0x1E, 0xBA, 0x1E, 0xBA, 0x1E, 241 | 0xBC, 0x1E, 0xBC, 0x1E, 0xBE, 0x1E, 0xBE, 0x1E, 0xC0, 0x1E, 0xC0, 0x1E, 0xC2, 0x1E, 0xC2, 0x1E, 242 | 0xC4, 0x1E, 0xC4, 0x1E, 0xC6, 0x1E, 0xC6, 0x1E, 0xC8, 0x1E, 0xC8, 0x1E, 0xCA, 0x1E, 0xCA, 0x1E, 243 | 0xCC, 0x1E, 0xCC, 0x1E, 0xCE, 0x1E, 0xCE, 0x1E, 0xD0, 0x1E, 0xD0, 0x1E, 0xD2, 0x1E, 0xD2, 0x1E, 244 | 0xD4, 0x1E, 0xD4, 0x1E, 0xD6, 0x1E, 0xD6, 0x1E, 0xD8, 0x1E, 0xD8, 0x1E, 0xDA, 0x1E, 0xDA, 0x1E, 245 | 0xDC, 0x1E, 0xDC, 0x1E, 0xDE, 0x1E, 0xDE, 0x1E, 0xE0, 0x1E, 0xE0, 0x1E, 0xE2, 0x1E, 0xE2, 0x1E, 246 | 0xE4, 0x1E, 0xE4, 0x1E, 0xE6, 0x1E, 0xE6, 0x1E, 0xE8, 0x1E, 0xE8, 0x1E, 0xEA, 0x1E, 0xEA, 0x1E, 247 | 0xEC, 0x1E, 0xEC, 0x1E, 0xEE, 0x1E, 0xEE, 0x1E, 0xF0, 0x1E, 0xF0, 0x1E, 0xF2, 0x1E, 0xF2, 0x1E, 248 | 0xF4, 0x1E, 0xF4, 0x1E, 0xF6, 0x1E, 0xF6, 0x1E, 0xF8, 0x1E, 0xF8, 0x1E, 0xFA, 0x1E, 0xFB, 0x1E, 249 | 0xFC, 0x1E, 0xFD, 0x1E, 0xFE, 0x1E, 0xFF, 0x1E, 0x08, 0x1F, 0x09, 0x1F, 0x0A, 0x1F, 0x0B, 0x1F, 250 | 0x0C, 0x1F, 0x0D, 0x1F, 0x0E, 0x1F, 0x0F, 0x1F, 0x08, 0x1F, 0x09, 0x1F, 0x0A, 0x1F, 0x0B, 0x1F, 251 | 0x0C, 0x1F, 0x0D, 0x1F, 0x0E, 0x1F, 0x0F, 0x1F, 0x18, 0x1F, 0x19, 0x1F, 0x1A, 0x1F, 0x1B, 0x1F, 252 | 0x1C, 0x1F, 0x1D, 0x1F, 0x16, 0x1F, 0x17, 0x1F, 0x18, 0x1F, 0x19, 0x1F, 0x1A, 0x1F, 0x1B, 0x1F, 253 | 0x1C, 0x1F, 0x1D, 0x1F, 0x1E, 0x1F, 0x1F, 0x1F, 0x28, 0x1F, 0x29, 0x1F, 0x2A, 0x1F, 0x2B, 0x1F, 254 | 0x2C, 0x1F, 0x2D, 0x1F, 0x2E, 0x1F, 0x2F, 0x1F, 0x28, 0x1F, 0x29, 0x1F, 0x2A, 0x1F, 0x2B, 0x1F, 255 | 0x2C, 0x1F, 0x2D, 0x1F, 0x2E, 0x1F, 0x2F, 0x1F, 0x38, 0x1F, 0x39, 0x1F, 0x3A, 0x1F, 0x3B, 0x1F, 256 | 0x3C, 0x1F, 0x3D, 0x1F, 0x3E, 0x1F, 0x3F, 0x1F, 0x38, 0x1F, 0x39, 0x1F, 0x3A, 0x1F, 0x3B, 0x1F, 257 | 0x3C, 0x1F, 0x3D, 0x1F, 0x3E, 0x1F, 0x3F, 0x1F, 0x48, 0x1F, 0x49, 0x1F, 0x4A, 0x1F, 0x4B, 0x1F, 258 | 0x4C, 0x1F, 0x4D, 0x1F, 0x46, 0x1F, 0x47, 0x1F, 0x48, 0x1F, 0x49, 0x1F, 0x4A, 0x1F, 0x4B, 0x1F, 259 | 0x4C, 0x1F, 0x4D, 0x1F, 0x4E, 0x1F, 0x4F, 0x1F, 0x50, 0x1F, 0x59, 0x1F, 0x52, 0x1F, 0x5B, 0x1F, 260 | 0x54, 0x1F, 0x5D, 0x1F, 0x56, 0x1F, 0x5F, 0x1F, 0x58, 0x1F, 0x59, 0x1F, 0x5A, 0x1F, 0x5B, 0x1F, 261 | 0x5C, 0x1F, 0x5D, 0x1F, 0x5E, 0x1F, 0x5F, 0x1F, 0x68, 0x1F, 0x69, 0x1F, 0x6A, 0x1F, 0x6B, 0x1F, 262 | 0x6C, 0x1F, 0x6D, 0x1F, 0x6E, 0x1F, 0x6F, 0x1F, 0x68, 0x1F, 0x69, 0x1F, 0x6A, 0x1F, 0x6B, 0x1F, 263 | 0x6C, 0x1F, 0x6D, 0x1F, 0x6E, 0x1F, 0x6F, 0x1F, 0xBA, 0x1F, 0xBB, 0x1F, 0xC8, 0x1F, 0xC9, 0x1F, 264 | 0xCA, 0x1F, 0xCB, 0x1F, 0xDA, 0x1F, 0xDB, 0x1F, 0xF8, 0x1F, 0xF9, 0x1F, 0xEA, 0x1F, 0xEB, 0x1F, 265 | 0xFA, 0x1F, 0xFB, 0x1F, 0x7E, 0x1F, 0x7F, 0x1F, 0x88, 0x1F, 0x89, 0x1F, 0x8A, 0x1F, 0x8B, 0x1F, 266 | 0x8C, 0x1F, 0x8D, 0x1F, 0x8E, 0x1F, 0x8F, 0x1F, 0x88, 0x1F, 0x89, 0x1F, 0x8A, 0x1F, 0x8B, 0x1F, 267 | 0x8C, 0x1F, 0x8D, 0x1F, 0x8E, 0x1F, 0x8F, 0x1F, 0x98, 0x1F, 0x99, 0x1F, 0x9A, 0x1F, 0x9B, 0x1F, 268 | 0x9C, 0x1F, 0x9D, 0x1F, 0x9E, 0x1F, 0x9F, 0x1F, 0x98, 0x1F, 0x99, 0x1F, 0x9A, 0x1F, 0x9B, 0x1F, 269 | 0x9C, 0x1F, 0x9D, 0x1F, 0x9E, 0x1F, 0x9F, 0x1F, 0xA8, 0x1F, 0xA9, 0x1F, 0xAA, 0x1F, 0xAB, 0x1F, 270 | 0xAC, 0x1F, 0xAD, 0x1F, 0xAE, 0x1F, 0xAF, 0x1F, 0xA8, 0x1F, 0xA9, 0x1F, 0xAA, 0x1F, 0xAB, 0x1F, 271 | 0xAC, 0x1F, 0xAD, 0x1F, 0xAE, 0x1F, 0xAF, 0x1F, 0xB8, 0x1F, 0xB9, 0x1F, 0xB2, 0x1F, 0xBC, 0x1F, 272 | 0xB4, 0x1F, 0xB5, 0x1F, 0xB6, 0x1F, 0xB7, 0x1F, 0xB8, 0x1F, 0xB9, 0x1F, 0xBA, 0x1F, 0xBB, 0x1F, 273 | 0xBC, 0x1F, 0xBD, 0x1F, 0xBE, 0x1F, 0xBF, 0x1F, 0xC0, 0x1F, 0xC1, 0x1F, 0xC2, 0x1F, 0xC3, 0x1F, 274 | 0xC4, 0x1F, 0xC5, 0x1F, 0xC6, 0x1F, 0xC7, 0x1F, 0xC8, 0x1F, 0xC9, 0x1F, 0xCA, 0x1F, 0xCB, 0x1F, 275 | 0xC3, 0x1F, 0xCD, 0x1F, 0xCE, 0x1F, 0xCF, 0x1F, 0xD8, 0x1F, 0xD9, 0x1F, 0xD2, 0x1F, 0xD3, 0x1F, 276 | 0xD4, 0x1F, 0xD5, 0x1F, 0xD6, 0x1F, 0xD7, 0x1F, 0xD8, 0x1F, 0xD9, 0x1F, 0xDA, 0x1F, 0xDB, 0x1F, 277 | 0xDC, 0x1F, 0xDD, 0x1F, 0xDE, 0x1F, 0xDF, 0x1F, 0xE8, 0x1F, 0xE9, 0x1F, 0xE2, 0x1F, 0xE3, 0x1F, 278 | 0xE4, 0x1F, 0xEC, 0x1F, 0xE6, 0x1F, 0xE7, 0x1F, 0xE8, 0x1F, 0xE9, 0x1F, 0xEA, 0x1F, 0xEB, 0x1F, 279 | 0xEC, 0x1F, 0xED, 0x1F, 0xEE, 0x1F, 0xEF, 0x1F, 0xF0, 0x1F, 0xF1, 0x1F, 0xF2, 0x1F, 0xF3, 0x1F, 280 | 0xF4, 0x1F, 0xF5, 0x1F, 0xF6, 0x1F, 0xF7, 0x1F, 0xF8, 0x1F, 0xF9, 0x1F, 0xFA, 0x1F, 0xFB, 0x1F, 281 | 0xF3, 0x1F, 0xFD, 0x1F, 0xFE, 0x1F, 0xFF, 0x1F, 0x00, 0x20, 0x01, 0x20, 0x02, 0x20, 0x03, 0x20, 282 | 0x04, 0x20, 0x05, 0x20, 0x06, 0x20, 0x07, 0x20, 0x08, 0x20, 0x09, 0x20, 0x0A, 0x20, 0x0B, 0x20, 283 | 0x0C, 0x20, 0x0D, 0x20, 0x0E, 0x20, 0x0F, 0x20, 0x10, 0x20, 0x11, 0x20, 0x12, 0x20, 0x13, 0x20, 284 | 0x14, 0x20, 0x15, 0x20, 0x16, 0x20, 0x17, 0x20, 0x18, 0x20, 0x19, 0x20, 0x1A, 0x20, 0x1B, 0x20, 285 | 0x1C, 0x20, 0x1D, 0x20, 0x1E, 0x20, 0x1F, 0x20, 0x20, 0x20, 0x21, 0x20, 0x22, 0x20, 0x23, 0x20, 286 | 0x24, 0x20, 0x25, 0x20, 0x26, 0x20, 0x27, 0x20, 0x28, 0x20, 0x29, 0x20, 0x2A, 0x20, 0x2B, 0x20, 287 | 0x2C, 0x20, 0x2D, 0x20, 0x2E, 0x20, 0x2F, 0x20, 0x30, 0x20, 0x31, 0x20, 0x32, 0x20, 0x33, 0x20, 288 | 0x34, 0x20, 0x35, 0x20, 0x36, 0x20, 0x37, 0x20, 0x38, 0x20, 0x39, 0x20, 0x3A, 0x20, 0x3B, 0x20, 289 | 0x3C, 0x20, 0x3D, 0x20, 0x3E, 0x20, 0x3F, 0x20, 0x40, 0x20, 0x41, 0x20, 0x42, 0x20, 0x43, 0x20, 290 | 0x44, 0x20, 0x45, 0x20, 0x46, 0x20, 0x47, 0x20, 0x48, 0x20, 0x49, 0x20, 0x4A, 0x20, 0x4B, 0x20, 291 | 0x4C, 0x20, 0x4D, 0x20, 0x4E, 0x20, 0x4F, 0x20, 0x50, 0x20, 0x51, 0x20, 0x52, 0x20, 0x53, 0x20, 292 | 0x54, 0x20, 0x55, 0x20, 0x56, 0x20, 0x57, 0x20, 0x58, 0x20, 0x59, 0x20, 0x5A, 0x20, 0x5B, 0x20, 293 | 0x5C, 0x20, 0x5D, 0x20, 0x5E, 0x20, 0x5F, 0x20, 0x60, 0x20, 0x61, 0x20, 0x62, 0x20, 0x63, 0x20, 294 | 0x64, 0x20, 0x65, 0x20, 0x66, 0x20, 0x67, 0x20, 0x68, 0x20, 0x69, 0x20, 0x6A, 0x20, 0x6B, 0x20, 295 | 0x6C, 0x20, 0x6D, 0x20, 0x6E, 0x20, 0x6F, 0x20, 0x70, 0x20, 0x71, 0x20, 0x72, 0x20, 0x73, 0x20, 296 | 0x74, 0x20, 0x75, 0x20, 0x76, 0x20, 0x77, 0x20, 0x78, 0x20, 0x79, 0x20, 0x7A, 0x20, 0x7B, 0x20, 297 | 0x7C, 0x20, 0x7D, 0x20, 0x7E, 0x20, 0x7F, 0x20, 0x80, 0x20, 0x81, 0x20, 0x82, 0x20, 0x83, 0x20, 298 | 0x84, 0x20, 0x85, 0x20, 0x86, 0x20, 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x8A, 0x20, 0x8B, 0x20, 299 | 0x8C, 0x20, 0x8D, 0x20, 0x8E, 0x20, 0x8F, 0x20, 0x90, 0x20, 0x91, 0x20, 0x92, 0x20, 0x93, 0x20, 300 | 0x94, 0x20, 0x95, 0x20, 0x96, 0x20, 0x97, 0x20, 0x98, 0x20, 0x99, 0x20, 0x9A, 0x20, 0x9B, 0x20, 301 | 0x9C, 0x20, 0x9D, 0x20, 0x9E, 0x20, 0x9F, 0x20, 0xA0, 0x20, 0xA1, 0x20, 0xA2, 0x20, 0xA3, 0x20, 302 | 0xA4, 0x20, 0xA5, 0x20, 0xA6, 0x20, 0xA7, 0x20, 0xA8, 0x20, 0xA9, 0x20, 0xAA, 0x20, 0xAB, 0x20, 303 | 0xAC, 0x20, 0xAD, 0x20, 0xAE, 0x20, 0xAF, 0x20, 0xB0, 0x20, 0xB1, 0x20, 0xB2, 0x20, 0xB3, 0x20, 304 | 0xB4, 0x20, 0xB5, 0x20, 0xB6, 0x20, 0xB7, 0x20, 0xB8, 0x20, 0xB9, 0x20, 0xBA, 0x20, 0xBB, 0x20, 305 | 0xBC, 0x20, 0xBD, 0x20, 0xBE, 0x20, 0xBF, 0x20, 0xC0, 0x20, 0xC1, 0x20, 0xC2, 0x20, 0xC3, 0x20, 306 | 0xC4, 0x20, 0xC5, 0x20, 0xC6, 0x20, 0xC7, 0x20, 0xC8, 0x20, 0xC9, 0x20, 0xCA, 0x20, 0xCB, 0x20, 307 | 0xCC, 0x20, 0xCD, 0x20, 0xCE, 0x20, 0xCF, 0x20, 0xD0, 0x20, 0xD1, 0x20, 0xD2, 0x20, 0xD3, 0x20, 308 | 0xD4, 0x20, 0xD5, 0x20, 0xD6, 0x20, 0xD7, 0x20, 0xD8, 0x20, 0xD9, 0x20, 0xDA, 0x20, 0xDB, 0x20, 309 | 0xDC, 0x20, 0xDD, 0x20, 0xDE, 0x20, 0xDF, 0x20, 0xE0, 0x20, 0xE1, 0x20, 0xE2, 0x20, 0xE3, 0x20, 310 | 0xE4, 0x20, 0xE5, 0x20, 0xE6, 0x20, 0xE7, 0x20, 0xE8, 0x20, 0xE9, 0x20, 0xEA, 0x20, 0xEB, 0x20, 311 | 0xEC, 0x20, 0xED, 0x20, 0xEE, 0x20, 0xEF, 0x20, 0xF0, 0x20, 0xF1, 0x20, 0xF2, 0x20, 0xF3, 0x20, 312 | 0xF4, 0x20, 0xF5, 0x20, 0xF6, 0x20, 0xF7, 0x20, 0xF8, 0x20, 0xF9, 0x20, 0xFA, 0x20, 0xFB, 0x20, 313 | 0xFC, 0x20, 0xFD, 0x20, 0xFE, 0x20, 0xFF, 0x20, 0x00, 0x21, 0x01, 0x21, 0x02, 0x21, 0x03, 0x21, 314 | 0x04, 0x21, 0x05, 0x21, 0x06, 0x21, 0x07, 0x21, 0x08, 0x21, 0x09, 0x21, 0x0A, 0x21, 0x0B, 0x21, 315 | 0x0C, 0x21, 0x0D, 0x21, 0x0E, 0x21, 0x0F, 0x21, 0x10, 0x21, 0x11, 0x21, 0x12, 0x21, 0x13, 0x21, 316 | 0x14, 0x21, 0x15, 0x21, 0x16, 0x21, 0x17, 0x21, 0x18, 0x21, 0x19, 0x21, 0x1A, 0x21, 0x1B, 0x21, 317 | 0x1C, 0x21, 0x1D, 0x21, 0x1E, 0x21, 0x1F, 0x21, 0x20, 0x21, 0x21, 0x21, 0x22, 0x21, 0x23, 0x21, 318 | 0x24, 0x21, 0x25, 0x21, 0x26, 0x21, 0x27, 0x21, 0x28, 0x21, 0x29, 0x21, 0x2A, 0x21, 0x2B, 0x21, 319 | 0x2C, 0x21, 0x2D, 0x21, 0x2E, 0x21, 0x2F, 0x21, 0x30, 0x21, 0x31, 0x21, 0x32, 0x21, 0x33, 0x21, 320 | 0x34, 0x21, 0x35, 0x21, 0x36, 0x21, 0x37, 0x21, 0x38, 0x21, 0x39, 0x21, 0x3A, 0x21, 0x3B, 0x21, 321 | 0x3C, 0x21, 0x3D, 0x21, 0x3E, 0x21, 0x3F, 0x21, 0x40, 0x21, 0x41, 0x21, 0x42, 0x21, 0x43, 0x21, 322 | 0x44, 0x21, 0x45, 0x21, 0x46, 0x21, 0x47, 0x21, 0x48, 0x21, 0x49, 0x21, 0x4A, 0x21, 0x4B, 0x21, 323 | 0x4C, 0x21, 0x4D, 0x21, 0x32, 0x21, 0x4F, 0x21, 0x50, 0x21, 0x51, 0x21, 0x52, 0x21, 0x53, 0x21, 324 | 0x54, 0x21, 0x55, 0x21, 0x56, 0x21, 0x57, 0x21, 0x58, 0x21, 0x59, 0x21, 0x5A, 0x21, 0x5B, 0x21, 325 | 0x5C, 0x21, 0x5D, 0x21, 0x5E, 0x21, 0x5F, 0x21, 0x60, 0x21, 0x61, 0x21, 0x62, 0x21, 0x63, 0x21, 326 | 0x64, 0x21, 0x65, 0x21, 0x66, 0x21, 0x67, 0x21, 0x68, 0x21, 0x69, 0x21, 0x6A, 0x21, 0x6B, 0x21, 327 | 0x6C, 0x21, 0x6D, 0x21, 0x6E, 0x21, 0x6F, 0x21, 0x60, 0x21, 0x61, 0x21, 0x62, 0x21, 0x63, 0x21, 328 | 0x64, 0x21, 0x65, 0x21, 0x66, 0x21, 0x67, 0x21, 0x68, 0x21, 0x69, 0x21, 0x6A, 0x21, 0x6B, 0x21, 329 | 0x6C, 0x21, 0x6D, 0x21, 0x6E, 0x21, 0x6F, 0x21, 0x80, 0x21, 0x81, 0x21, 0x82, 0x21, 0x83, 0x21, 330 | 0x83, 0x21, 0xFF, 0xFF, 0x4B, 0x03, 0xB6, 0x24, 0xB7, 0x24, 0xB8, 0x24, 0xB9, 0x24, 0xBA, 0x24, 331 | 0xBB, 0x24, 0xBC, 0x24, 0xBD, 0x24, 0xBE, 0x24, 0xBF, 0x24, 0xC0, 0x24, 0xC1, 0x24, 0xC2, 0x24, 332 | 0xC3, 0x24, 0xC4, 0x24, 0xC5, 0x24, 0xC6, 0x24, 0xC7, 0x24, 0xC8, 0x24, 0xC9, 0x24, 0xCA, 0x24, 333 | 0xCB, 0x24, 0xCC, 0x24, 0xCD, 0x24, 0xCE, 0x24, 0xCF, 0x24, 0xFF, 0xFF, 0x46, 0x07, 0x00, 0x2C, 334 | 0x01, 0x2C, 0x02, 0x2C, 0x03, 0x2C, 0x04, 0x2C, 0x05, 0x2C, 0x06, 0x2C, 0x07, 0x2C, 0x08, 0x2C, 335 | 0x09, 0x2C, 0x0A, 0x2C, 0x0B, 0x2C, 0x0C, 0x2C, 0x0D, 0x2C, 0x0E, 0x2C, 0x0F, 0x2C, 0x10, 0x2C, 336 | 0x11, 0x2C, 0x12, 0x2C, 0x13, 0x2C, 0x14, 0x2C, 0x15, 0x2C, 0x16, 0x2C, 0x17, 0x2C, 0x18, 0x2C, 337 | 0x19, 0x2C, 0x1A, 0x2C, 0x1B, 0x2C, 0x1C, 0x2C, 0x1D, 0x2C, 0x1E, 0x2C, 0x1F, 0x2C, 0x20, 0x2C, 338 | 0x21, 0x2C, 0x22, 0x2C, 0x23, 0x2C, 0x24, 0x2C, 0x25, 0x2C, 0x26, 0x2C, 0x27, 0x2C, 0x28, 0x2C, 339 | 0x29, 0x2C, 0x2A, 0x2C, 0x2B, 0x2C, 0x2C, 0x2C, 0x2D, 0x2C, 0x2E, 0x2C, 0x5F, 0x2C, 0x60, 0x2C, 340 | 0x60, 0x2C, 0x62, 0x2C, 0x63, 0x2C, 0x64, 0x2C, 0x65, 0x2C, 0x66, 0x2C, 0x67, 0x2C, 0x67, 0x2C, 341 | 0x69, 0x2C, 0x69, 0x2C, 0x6B, 0x2C, 0x6B, 0x2C, 0x6D, 0x2C, 0x6E, 0x2C, 0x6F, 0x2C, 0x70, 0x2C, 342 | 0x71, 0x2C, 0x72, 0x2C, 0x73, 0x2C, 0x74, 0x2C, 0x75, 0x2C, 0x75, 0x2C, 0x77, 0x2C, 0x78, 0x2C, 343 | 0x79, 0x2C, 0x7A, 0x2C, 0x7B, 0x2C, 0x7C, 0x2C, 0x7D, 0x2C, 0x7E, 0x2C, 0x7F, 0x2C, 0x80, 0x2C, 344 | 0x80, 0x2C, 0x82, 0x2C, 0x82, 0x2C, 0x84, 0x2C, 0x84, 0x2C, 0x86, 0x2C, 0x86, 0x2C, 0x88, 0x2C, 345 | 0x88, 0x2C, 0x8A, 0x2C, 0x8A, 0x2C, 0x8C, 0x2C, 0x8C, 0x2C, 0x8E, 0x2C, 0x8E, 0x2C, 0x90, 0x2C, 346 | 0x90, 0x2C, 0x92, 0x2C, 0x92, 0x2C, 0x94, 0x2C, 0x94, 0x2C, 0x96, 0x2C, 0x96, 0x2C, 0x98, 0x2C, 347 | 0x98, 0x2C, 0x9A, 0x2C, 0x9A, 0x2C, 0x9C, 0x2C, 0x9C, 0x2C, 0x9E, 0x2C, 0x9E, 0x2C, 0xA0, 0x2C, 348 | 0xA0, 0x2C, 0xA2, 0x2C, 0xA2, 0x2C, 0xA4, 0x2C, 0xA4, 0x2C, 0xA6, 0x2C, 0xA6, 0x2C, 0xA8, 0x2C, 349 | 0xA8, 0x2C, 0xAA, 0x2C, 0xAA, 0x2C, 0xAC, 0x2C, 0xAC, 0x2C, 0xAE, 0x2C, 0xAE, 0x2C, 0xB0, 0x2C, 350 | 0xB0, 0x2C, 0xB2, 0x2C, 0xB2, 0x2C, 0xB4, 0x2C, 0xB4, 0x2C, 0xB6, 0x2C, 0xB6, 0x2C, 0xB8, 0x2C, 351 | 0xB8, 0x2C, 0xBA, 0x2C, 0xBA, 0x2C, 0xBC, 0x2C, 0xBC, 0x2C, 0xBE, 0x2C, 0xBE, 0x2C, 0xC0, 0x2C, 352 | 0xC0, 0x2C, 0xC2, 0x2C, 0xC2, 0x2C, 0xC4, 0x2C, 0xC4, 0x2C, 0xC6, 0x2C, 0xC6, 0x2C, 0xC8, 0x2C, 353 | 0xC8, 0x2C, 0xCA, 0x2C, 0xCA, 0x2C, 0xCC, 0x2C, 0xCC, 0x2C, 0xCE, 0x2C, 0xCE, 0x2C, 0xD0, 0x2C, 354 | 0xD0, 0x2C, 0xD2, 0x2C, 0xD2, 0x2C, 0xD4, 0x2C, 0xD4, 0x2C, 0xD6, 0x2C, 0xD6, 0x2C, 0xD8, 0x2C, 355 | 0xD8, 0x2C, 0xDA, 0x2C, 0xDA, 0x2C, 0xDC, 0x2C, 0xDC, 0x2C, 0xDE, 0x2C, 0xDE, 0x2C, 0xE0, 0x2C, 356 | 0xE0, 0x2C, 0xE2, 0x2C, 0xE2, 0x2C, 0xE4, 0x2C, 0xE5, 0x2C, 0xE6, 0x2C, 0xE7, 0x2C, 0xE8, 0x2C, 357 | 0xE9, 0x2C, 0xEA, 0x2C, 0xEB, 0x2C, 0xEC, 0x2C, 0xED, 0x2C, 0xEE, 0x2C, 0xEF, 0x2C, 0xF0, 0x2C, 358 | 0xF1, 0x2C, 0xF2, 0x2C, 0xF3, 0x2C, 0xF4, 0x2C, 0xF5, 0x2C, 0xF6, 0x2C, 0xF7, 0x2C, 0xF8, 0x2C, 359 | 0xF9, 0x2C, 0xFA, 0x2C, 0xFB, 0x2C, 0xFC, 0x2C, 0xFD, 0x2C, 0xFE, 0x2C, 0xFF, 0x2C, 0xA0, 0x10, 360 | 0xA1, 0x10, 0xA2, 0x10, 0xA3, 0x10, 0xA4, 0x10, 0xA5, 0x10, 0xA6, 0x10, 0xA7, 0x10, 0xA8, 0x10, 361 | 0xA9, 0x10, 0xAA, 0x10, 0xAB, 0x10, 0xAC, 0x10, 0xAD, 0x10, 0xAE, 0x10, 0xAF, 0x10, 0xB0, 0x10, 362 | 0xB1, 0x10, 0xB2, 0x10, 0xB3, 0x10, 0xB4, 0x10, 0xB5, 0x10, 0xB6, 0x10, 0xB7, 0x10, 0xB8, 0x10, 363 | 0xB9, 0x10, 0xBA, 0x10, 0xBB, 0x10, 0xBC, 0x10, 0xBD, 0x10, 0xBE, 0x10, 0xBF, 0x10, 0xC0, 0x10, 364 | 0xC1, 0x10, 0xC2, 0x10, 0xC3, 0x10, 0xC4, 0x10, 0xC5, 0x10, 0xFF, 0xFF, 0x1B, 0xD2, 0x21, 0xFF, 365 | 0x22, 0xFF, 0x23, 0xFF, 0x24, 0xFF, 0x25, 0xFF, 0x26, 0xFF, 0x27, 0xFF, 0x28, 0xFF, 0x29, 0xFF, 366 | 0x2A, 0xFF, 0x2B, 0xFF, 0x2C, 0xFF, 0x2D, 0xFF, 0x2E, 0xFF, 0x2F, 0xFF, 0x30, 0xFF, 0x31, 0xFF, 367 | 0x32, 0xFF, 0x33, 0xFF, 0x34, 0xFF, 0x35, 0xFF, 0x36, 0xFF, 0x37, 0xFF, 0x38, 0xFF, 0x39, 0xFF, 368 | 0x3A, 0xFF, 0x5B, 0xFF, 0x5C, 0xFF, 0x5D, 0xFF, 0x5E, 0xFF, 0x5F, 0xFF, 0x60, 0xFF, 0x61, 0xFF, 369 | 0x62, 0xFF, 0x63, 0xFF, 0x64, 0xFF, 0x65, 0xFF, 0x66, 0xFF, 0x67, 0xFF, 0x68, 0xFF, 0x69, 0xFF, 370 | 0x6A, 0xFF, 0x6B, 0xFF, 0x6C, 0xFF, 0x6D, 0xFF, 0x6E, 0xFF, 0x6F, 0xFF, 0x70, 0xFF, 0x71, 0xFF, 371 | 0x72, 0xFF, 0x73, 0xFF, 0x74, 0xFF, 0x75, 0xFF, 0x76, 0xFF, 0x77, 0xFF, 0x78, 0xFF, 0x79, 0xFF, 372 | 0x7A, 0xFF, 0x7B, 0xFF, 0x7C, 0xFF, 0x7D, 0xFF, 0x7E, 0xFF, 0x7F, 0xFF, 0x80, 0xFF, 0x81, 0xFF, 373 | 0x82, 0xFF, 0x83, 0xFF, 0x84, 0xFF, 0x85, 0xFF, 0x86, 0xFF, 0x87, 0xFF, 0x88, 0xFF, 0x89, 0xFF, 374 | 0x8A, 0xFF, 0x8B, 0xFF, 0x8C, 0xFF, 0x8D, 0xFF, 0x8E, 0xFF, 0x8F, 0xFF, 0x90, 0xFF, 0x91, 0xFF, 375 | 0x92, 0xFF, 0x93, 0xFF, 0x94, 0xFF, 0x95, 0xFF, 0x96, 0xFF, 0x97, 0xFF, 0x98, 0xFF, 0x99, 0xFF, 376 | 0x9A, 0xFF, 0x9B, 0xFF, 0x9C, 0xFF, 0x9D, 0xFF, 0x9E, 0xFF, 0x9F, 0xFF, 0xA0, 0xFF, 0xA1, 0xFF, 377 | 0xA2, 0xFF, 0xA3, 0xFF, 0xA4, 0xFF, 0xA5, 0xFF, 0xA6, 0xFF, 0xA7, 0xFF, 0xA8, 0xFF, 0xA9, 0xFF, 378 | 0xAA, 0xFF, 0xAB, 0xFF, 0xAC, 0xFF, 0xAD, 0xFF, 0xAE, 0xFF, 0xAF, 0xFF, 0xB0, 0xFF, 0xB1, 0xFF, 379 | 0xB2, 0xFF, 0xB3, 0xFF, 0xB4, 0xFF, 0xB5, 0xFF, 0xB6, 0xFF, 0xB7, 0xFF, 0xB8, 0xFF, 0xB9, 0xFF, 380 | 0xBA, 0xFF, 0xBB, 0xFF, 0xBC, 0xFF, 0xBD, 0xFF, 0xBE, 0xFF, 0xBF, 0xFF, 0xC0, 0xFF, 0xC1, 0xFF, 381 | 0xC2, 0xFF, 0xC3, 0xFF, 0xC4, 0xFF, 0xC5, 0xFF, 0xC6, 0xFF, 0xC7, 0xFF, 0xC8, 0xFF, 0xC9, 0xFF, 382 | 0xCA, 0xFF, 0xCB, 0xFF, 0xCC, 0xFF, 0xCD, 0xFF, 0xCE, 0xFF, 0xCF, 0xFF, 0xD0, 0xFF, 0xD1, 0xFF, 383 | 0xD2, 0xFF, 0xD3, 0xFF, 0xD4, 0xFF, 0xD5, 0xFF, 0xD6, 0xFF, 0xD7, 0xFF, 0xD8, 0xFF, 0xD9, 0xFF, 384 | 0xDA, 0xFF, 0xDB, 0xFF, 0xDC, 0xFF, 0xDD, 0xFF, 0xDE, 0xFF, 0xDF, 0xFF, 0xE0, 0xFF, 0xE1, 0xFF, 385 | 0xE2, 0xFF, 0xE3, 0xFF, 0xE4, 0xFF, 0xE5, 0xFF, 0xE6, 0xFF, 0xE7, 0xFF, 0xE8, 0xFF, 0xE9, 0xFF, 386 | 0xEA, 0xFF, 0xEB, 0xFF, 0xEC, 0xFF, 0xED, 0xFF, 0xEE, 0xFF, 0xEF, 0xFF, 0xF0, 0xFF, 0xF1, 0xFF, 387 | 0xF2, 0xFF, 0xF3, 0xFF, 0xF4, 0xFF, 0xF5, 0xFF, 0xF6, 0xFF, 0xF7, 0xFF, 0xF8, 0xFF, 0xF9, 0xFF, 388 | 0xFA, 0xFF, 0xFB, 0xFF, 0xFC, 0xFF, 0xFD, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF 389 | }; 390 | -------------------------------------------------------------------------------- /exfat_xattr.c: -------------------------------------------------------------------------------- 1 | #include "exfat.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #ifndef CONFIG_EXFAT_VIRTUAL_XATTR_SELINUX_LABEL 9 | #define CONFIG_EXFAT_VIRTUAL_XATTR_SELINUX_LABEL ("undefined") 10 | #endif 11 | 12 | static const char default_xattr[] = CONFIG_EXFAT_VIRTUAL_XATTR_SELINUX_LABEL; 13 | 14 | int exfat_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) { 15 | if (!name || strcmp(name, "security.selinux")) 16 | return -EOPNOTSUPP; 17 | return 0; 18 | } 19 | 20 | ssize_t exfat_getxattr(struct dentry *dentry, const char *name, void *value, size_t size) { 21 | if (!name || strcmp(name, "security.selinux")) 22 | return -EOPNOTSUPP; 23 | if (size > strlen(default_xattr)+1 && value) 24 | strcpy(value, default_xattr); 25 | return strlen(default_xattr); 26 | } 27 | 28 | ssize_t exfat_listxattr(struct dentry *dentry, char *list, size_t size) { 29 | return 0; 30 | } 31 | 32 | int exfat_removexattr(struct dentry *dentry, const char *name) { 33 | if (!name || strcmp(name, "security.selinux")) 34 | return -EOPNOTSUPP; 35 | return 0; 36 | } 37 | --------------------------------------------------------------------------------