/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* Portions of this source code were derived from Berkeley 4.3 BSD
* under license from the Regents of the University of California.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* libfstyp module for pcfs
*/
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <locale.h>
#include <libfstyp_module.h>
struct fstyp_fat16_bs {
};
struct fstyp_fat32_bs {
};
typedef struct fstyp_pcfs {
int fd;
int fattype;
/* parameters derived or calculated per FAT spec */
} fstyp_pcfs_t;
/* We should eventually make the structs "packed" so these won't be needed */
static int read_bootsec(fstyp_pcfs_t *h);
static int valid_media(fstyp_pcfs_t *h);
static int well_formed(fstyp_pcfs_t *h);
static void calculate_parameters(fstyp_pcfs_t *h);
static void determine_fattype(fstyp_pcfs_t *h);
static void get_label(fstyp_pcfs_t *h);
static void get_label_16(fstyp_pcfs_t *h);
static void get_label_32(fstyp_pcfs_t *h);
static int next_cluster_32(fstyp_pcfs_t *h, int n);
static int is_pcfs(fstyp_pcfs_t *h);
static int get_attr(fstyp_pcfs_t *h);
int
{
struct fstyp_pcfs *h;
return (FSTYP_ERR_NOMEM);
}
*handle = (fstyp_mod_handle_t)h;
return (0);
}
void
{
nvlist_free(h->attr);
}
free(h);
}
int
{
return (is_pcfs(h));
}
int
{
int error;
return (FSTYP_ERR_NOMEM);
}
nvlist_free(h->attr);
return (error);
}
}
return (0);
}
int
{
}
/*
* Read in boot sector. Convert into host endianness where possible.
*/
static int
{
return (FSTYP_ERR_IO);
}
return (0);
}
static int
{
switch (h->bs.mediadesriptor) {
case MD_FIXED:
case SS8SPT:
case DS8SPT:
case SS9SPT:
case DS9SPT:
case DS18SPT:
case DS9_15SPT:
return (1);
default:
return (0);
}
}
static int
{
int fatmatch;
PC_NSEC(h) > 0));
PC_NSEC(h) > 0));
} else {
}
}
static void
{
if (PC_NSEC(h) != 0) {
} else {
}
} else {
}
return;
}
h->RootDirSectors =
h->FirstDataSector =
}
static void
{
h->fattype = 0;
} else if (h->CountOfClusters < 4085) {
h->fattype = 12;
} else if (h->CountOfClusters < 65525) {
h->fattype = 16;
} else {
h->fattype = 32;
}
}
static void
{
/*
* Use label from the boot sector by default.
* Can overwrite later with the one from root directory.
*/
if (h->fattype == 0) {
return;
} else if (FSTYP_IS_32(h)) {
get_label_32(h);
} else {
get_label_16(h);
}
}
/*
* Get volume label from the root directory entry.
* In FAT12/16 the root directory is of fixed size.
* It immediately follows the FATs
*/
static void
{
int secsize;
int i;
return;
}
resid = PC_NROOTENT(h);
for (i = 0; i < h->RootDirSectors; i++) {
return;
}
}
return;
}
offset += PC_SECSIZE;
}
}
/*
* Get volume label from the root directory entry.
* In FAT32 root is a usual directory, a cluster chain.
* It starts at BPB_RootClus.
*/
static void
{
int clustersize;
int n;
int nent;
int cnt = 0;
return;
}
break;
}
break;
}
break;
}
}
}
/*
* Get a FAT entry pointing to the next file cluster
*/
int
{
int next = 0;
}
return (next);
}
/*
* Given an array of pcdir structs, find one containing volume label.
*/
static boolean_t
{
int i;
for (i = 0; i < nent; i++, d++) {
if (PCDL_IS_LFN(d))
continue;
if ((d->pcd_filename[0] != PCD_UNUSED) &&
(d->pcd_filename[0] != PCD_ERASED) &&
(d->un.pcd_scluster_hi == 0) &&
(d->pcd_scluster_lo == 0)) {
return (B_TRUE);
}
}
return (B_FALSE);
}
static int
{
int error;
if ((error = read_bootsec(h)) != 0) {
return (error);
}
if (!valid_media(h)) {
return (FSTYP_ERR_NO_MATCH);
}
if (!well_formed(h)) {
return (FSTYP_ERR_NO_MATCH);
}
get_label(h);
return (0);
}
/* ARGSUSED */
static int
{
"Bytes Per Sector %d\t\tSectors Per Cluster %d\n",
"Reserved Sectors %d\t\tNumber of FATs %d\n",
"Root Dir Entries %d\t\tNumber of Sectors %d\n",
(unsigned short)PC_NROOTENT(h), (unsigned short)PC_NSEC(h));
"Sectors Per FAT %d\t\tSectors Per Track %d\n",
"Number of Heads %d\t\tNumber Hidden Sectors %d\n",
switch (h->bs.mediadesriptor) {
case MD_FIXED:
break;
case SS8SPT:
break;
case DS8SPT:
break;
case SS9SPT:
break;
case DS9SPT:
break;
case DS18SPT:
break;
case DS9_15SPT:
break;
default:
}
return (0);
}
return (FSTYP_ERR_NOMEM); \
}
return (FSTYP_ERR_NOMEM); \
}
return (FSTYP_ERR_NOMEM); \
}
return (FSTYP_ERR_NOMEM); \
}
static int
{
char s[64];
if (FSTYP_IS_32(h)) {
}
if (PC_VOLID(a) != 0) {
ADD_STRING(h, "gen_guid", s);
}
ADD_STRING(h, "gen_version", s);
return (0);
}