1 /*- 2 * Copyright (c) 2004 Pawel Jakub Dawidek <pjd@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 30 #include <sys/param.h> 31 #include <sys/systm.h> 32 #include <sys/kernel.h> 33 #include <sys/malloc.h> 34 35 #include <geom/geom.h> 36 #include <geom/label/g_label.h> 37 38 #define G_LABEL_MSDOSFS_DIR "msdosfs" 39 40 #define FAT12 "FAT12 " 41 #define FAT16 "FAT16 " 42 #define FAT32 "FAT32 " 43 #define VOLUME_LEN 11 44 #define NO_NAME "NO NAME " 45 46 47 static void 48 g_label_msdosfs_taste(struct g_consumer *cp, char *label, size_t size) 49 { 50 struct g_provider *pp; 51 char *sector, *volume; 52 int i, error; 53 54 g_topology_assert_not(); 55 pp = cp->provider; 56 label[0] = '\0'; 57 58 sector = (char *)g_read_data(cp, 0, pp->sectorsize, &error); 59 if (sector == NULL || error != 0) 60 return; 61 if (strncmp(sector + 0x36, FAT12, strlen(FAT12)) == 0) { 62 G_LABEL_DEBUG(1, "MSDOS (FAT12) file system detected on %s.", 63 pp->name); 64 volume = sector + 0x2b; 65 } else if (strncmp(sector + 0x36, FAT16, strlen(FAT16)) == 0) { 66 G_LABEL_DEBUG(1, "MSDOS (FAT16) file system detected on %s.", 67 pp->name); 68 volume = sector + 0x2b; 69 } else if (strncmp(sector + 0x52, FAT32, strlen(FAT32)) == 0) { 70 G_LABEL_DEBUG(1, "MSDOS (FAT32) file system detected on %s.", 71 pp->name); 72 volume = sector + 0x47; 73 } else { 74 g_free(sector); 75 return; 76 } 77 if (strncmp(volume, NO_NAME, VOLUME_LEN) == 0) { 78 g_free(sector); 79 return; 80 } 81 if (volume[0] == '\0') { 82 g_free(sector); 83 return; 84 } 85 bzero(label, size); 86 strlcpy(label, volume, MIN(size, VOLUME_LEN)); 87 g_free(sector); 88 for (i = size - 1; i > 0; i--) { 89 if (label[i] == '\0') 90 continue; 91 else if (label[i] == ' ') 92 label[i] = '\0'; 93 else 94 break; 95 } 96 } 97 98 const struct g_label_desc g_label_msdosfs = { 99 .ld_taste = g_label_msdosfs_taste, 100 .ld_dir = G_LABEL_MSDOSFS_DIR 101 }; 102