g_label_msdosfs.c revision 131476
1131476Spjd/*- 2131476Spjd * Copyright (c) 2004 Pawel Jakub Dawidek <pjd@FreeBSD.org> 3131476Spjd * All rights reserved. 4131476Spjd * 5131476Spjd * Redistribution and use in source and binary forms, with or without 6131476Spjd * modification, are permitted provided that the following conditions 7131476Spjd * are met: 8131476Spjd * 1. Redistributions of source code must retain the above copyright 9131476Spjd * notice, this list of conditions and the following disclaimer. 10131476Spjd * 2. Redistributions in binary form must reproduce the above copyright 11131476Spjd * notice, this list of conditions and the following disclaimer in the 12131476Spjd * documentation and/or other materials provided with the distribution. 13131476Spjd * 14131476Spjd * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 15131476Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16131476Spjd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17131476Spjd * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 18131476Spjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19131476Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20131476Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21131476Spjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22131476Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23131476Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24131476Spjd * SUCH DAMAGE. 25131476Spjd */ 26131476Spjd 27131476Spjd#include <sys/cdefs.h> 28131476Spjd__FBSDID("$FreeBSD: head/sys/geom/label/g_label_msdosfs.c 131476 2004-07-02 19:40:36Z pjd $"); 29131476Spjd 30131476Spjd#include <sys/param.h> 31131476Spjd#include <sys/systm.h> 32131476Spjd#include <sys/kernel.h> 33131476Spjd#include <sys/malloc.h> 34131476Spjd 35131476Spjd#include <geom/geom.h> 36131476Spjd#include <geom/label/g_label.h> 37131476Spjd 38131476Spjd#define G_LABEL_MSDOSFS_DIR "msdosfs" 39131476Spjd 40131476Spjd#define FAT12 "FAT12 " 41131476Spjd#define FAT16 "FAT16 " 42131476Spjd#define FAT32 "FAT32 " 43131476Spjd#define VOLUME_LEN 11 44131476Spjd#define NO_NAME "NO NAME " 45131476Spjd 46131476Spjd 47131476Spjdstatic void 48131476Spjdg_label_msdosfs_taste(struct g_consumer *cp, char *label, size_t size) 49131476Spjd{ 50131476Spjd struct g_provider *pp; 51131476Spjd char *sector, *volume; 52131476Spjd int i, error; 53131476Spjd 54131476Spjd g_topology_assert_not(); 55131476Spjd pp = cp->provider; 56131476Spjd label[0] = '\0'; 57131476Spjd 58131476Spjd sector = (char *)g_read_data(cp, 0, pp->sectorsize, &error); 59131476Spjd if (sector == NULL || error != 0) 60131476Spjd return; 61131476Spjd if (strncmp(sector + 0x36, FAT12, strlen(FAT12)) == 0) { 62131476Spjd G_LABEL_DEBUG(1, "MSDOS (FAT12) file system detected on %s.", 63131476Spjd pp->name); 64131476Spjd volume = sector + 0x2b; 65131476Spjd } else if (strncmp(sector + 0x36, FAT16, strlen(FAT16)) == 0) { 66131476Spjd G_LABEL_DEBUG(1, "MSDOS (FAT16) file system detected on %s.", 67131476Spjd pp->name); 68131476Spjd volume = sector + 0x2b; 69131476Spjd } else if (strncmp(sector + 0x52, FAT32, strlen(FAT32)) == 0) { 70131476Spjd G_LABEL_DEBUG(1, "MSDOS (FAT32) file system detected on %s.", 71131476Spjd pp->name); 72131476Spjd volume = sector + 0x47; 73131476Spjd } else { 74131476Spjd g_free(sector); 75131476Spjd return; 76131476Spjd } 77131476Spjd if (strncmp(volume, NO_NAME, VOLUME_LEN) == 0) { 78131476Spjd g_free(sector); 79131476Spjd return; 80131476Spjd } 81131476Spjd if (volume[0] == '\0') { 82131476Spjd g_free(sector); 83131476Spjd return; 84131476Spjd } 85131476Spjd bzero(label, size); 86131476Spjd strlcpy(label, volume, MIN(size, VOLUME_LEN)); 87131476Spjd g_free(sector); 88131476Spjd for (i = size - 1; i > 0; i--) { 89131476Spjd if (label[i] == '\0') 90131476Spjd continue; 91131476Spjd else if (label[i] == ' ') 92131476Spjd label[i] = '\0'; 93131476Spjd else 94131476Spjd break; 95131476Spjd } 96131476Spjd} 97131476Spjd 98131476Spjdconst struct g_label_desc g_label_msdosfs = { 99131476Spjd .ld_taste = g_label_msdosfs_taste, 100131476Spjd .ld_dir = G_LABEL_MSDOSFS_DIR 101131476Spjd}; 102