⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dosfslib.c

📁 vxworks操作系统的文件系统部分原代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    	{    	dosFsBadBootMsg( 1, DOS_BOOT_BYTES_PER_SEC, work, NULL, __LINE__ );    	ERR_MSG(1, "bytesPerSec = 0\n", 0,0,0,0,0,0 );    	goto error;    	}    if( work != cbioParams.bytesPerBlk )    	{        dosFsBadBootMsg( 1, DOS_BOOT_BYTES_PER_SEC, work, NULL, __LINE__ );    	ERR_MSG(1, "cbioParams.bytesPerBlk %u != bytes-per-sec %u\n",     		   cbioParams.bytesPerBlk, work, 0,0,0,0 );    	goto error;    	}    /*     * bytes-per-sector must be a power-of-two per Microsoft FAT specification      * and at least 32 bytes, so a shift is used instead of multiplication in      * operations with this value.     */    pVolDesc->secSizeShift = 0;    for( work = 5; work < 16; work ++ )    	{    	if( (1 << work) == pVolDesc->bytesPerSec )    	    {    	    pVolDesc->secSizeShift = work;    	    break;    	    }    	}    if( pVolDesc->secSizeShift == 0 )    	{        dosFsBadBootMsg( 1, DOS_BOOT_BYTES_PER_SEC, 			 pVolDesc->bytesPerSec, NULL, __LINE__ );    	goto error;    	}    	    /* evaluate the total number of sectors on this volume */        work = DISK_TO_VX_16( bootSec + DOS_BOOT_NSECTORS );    /*      * When the volume has at least 0x10000 sectors, the 16 bit field      * DOS_BOOT_NSECTORS is zero, and the alternate 32bit field      * DOS_BOOT_LONG_NSECTORS is used to determine the number of      * sectors on the volume.     */    if( work == 0 )	/* it is a large disk */    	{    	work = DISK_TO_VX_32( bootSec + DOS_BOOT_LONG_NSECTORS );    	if( work == 0 )    	    {    	    dosFsBadBootMsg( 1, DOS_BOOT_LONG_NSECTORS, work,                             NULL, __LINE__ );    	    goto error;    	    }    	}    pVolDesc->totalSec = work;         /* number of sectors can be greater than cbioParams.nBlocks */         if( work != cbioParams.nBlocks )    	{	/* 	 * XXX - An error here may indicate a problem with representing	 * a partition size correctly in the underlying CBIO layer.         *          * Also, an off by one error may mean a driver bug.         * cbioParams.nBlocks is the number of blocks on the          * CBIO device. Using the "last addressable LBA value"         * in nBlocks can produce an off by one error, this is          * considered a driver problem.  bd_nBlocks shall be the          * number of blocks (1-xxx) not the last addressable block.           * Rather the driver should set nBlocks to the          * (last addressable block + 1).  DOSFS1 did not make this          * check.  DOSFS2 does make this check to avoid overrun.	 */    	if( work < cbioParams.nBlocks )    	    {    	    ERR_MSG(10, 		"WARNING: num-sectors %u < cbioParams.nBlocks %u\n",    		    work, cbioParams.nBlocks, 0,0,0,0 );    	    }    	else    	    {    	    dosFsBadBootMsg( 1, DOS_BOOT_LONG_NSECTORS, 0,                             NULL, __LINE__ );    	    ERR_MSG(1, "num-sectors %u > cbioParams.nBlocks %u\n",     		    work, cbioParams.nBlocks, 0,0,0,0 );    	    goto error;    	    }    	}        /* evaluate the number of sectors per cluster */        pVolDesc->secPerClust = bootSec[ DOS_BOOT_SEC_PER_CLUST ];    if( pVolDesc->secPerClust == 0 )    	{    	dosFsBadBootMsg( 1, DOS_BOOT_SEC_PER_CLUST, 0,                         NULL, __LINE__ );    	goto error;    	}        /* evaluate the number of FAT copies */        pVolDesc->nFats = bootSec[ DOS_BOOT_NFATS ];    if( pVolDesc->nFats == 0 )    	{    	dosFsBadBootMsg( 1, DOS_BOOT_NFATS, 0, NULL, __LINE__ );    	goto error;    	}    	    /* get the number of hidden sectors */        pVolDesc->nHiddenSecs = DISK_TO_VX_16( bootSec + DOS_BOOT_NHIDDEN_SECS);        /* evaluate the number of reserved sectors */        pVolDesc->nReservedSecs = DISK_TO_VX_16( bootSec + DOS_BOOT_NRESRVD_SECS);    if( pVolDesc->nReservedSecs == 0 )    	{    	dosFsBadBootMsg( 1, DOS_BOOT_NRESRVD_SECS, 0,                         NULL, __LINE__ );    	goto error;    	}    /* evaluate the number of sectors alloted to FAT table */    pVolDesc->secPerFat = DISK_TO_VX_16( bootSec + DOS_BOOT_SEC_PER_FAT );    /*      * Now determine the volumes FAT type.  FAT12, FAT16, and FAT32.     * NOTE: The secPerFat field is zero on FAT32 DOSFS volumes.      * This is how we determine if FAT32 will be used when mounting      * this volume.  If secPerFat is zero, it must be FAT32.     * Else, we need to pick between FAT12 and FAT16.     */    if( pVolDesc->secPerFat != 0 ) /* then using either FAT12 or FAT16 */    	{	/* 	 * The maximum number of 16 bit FAT entries is 65536. 	 * Anything greater is invalid.  Check here.	 */   	if( pVolDesc->secPerFat >  (ULONG)0x10000*2 / pVolDesc->bytesPerSec)    	    {    	    dosFsBadBootMsg( 1, DOS_BOOT_SEC_PER_FAT,			     pVolDesc->secPerFat, NULL, __LINE__ );    	    ERR_MSG(1, "secPerFat 12/16 = %u, while BPS = %u\n",    	    		pVolDesc->secPerFat,pVolDesc->bytesPerSec,0,0,0,0 );    	    goto error;    	    }    		/* 	 * Now we must decide if our volume is using FAT12 or FAT16.	 * If we choose the wrong FAT type, volume mounting will fail, 	 * and/or data corruption on the volume will occur when its exercised.	 * See also: SPR#34704.	 * We will also check the MS FSTYPE field (offset 0x36 in the 	 * boot sector) when determining the FAT type.  If either of the 	 * Microsoft defined strings exist, then we honor the boot sectors 	 * wisdom.  This presumes that the formatter of the volume knew what	 * they were doing when writing out these strings.  This may not	 * be the case, but its seems the most compatible approach.	 * The FSTYPE string field is also intentionaly being honored, so 	 * that either FAT type can be forced in the field.  In the event 	 * of a bad mount occuring in the field, a hack of writing the correct 	 * string to the BPB FSTYPE field would force the mount to the desired 	 * type.  Many DOS implementations do not set these strings and that 	 * is just fine.  Copy FSTYPE string to tmpType.	 */	bcopy ( (char *) bootSec + DOS_BOOT_FSTYPE_ID,                (char *) tmpType, DOS_BOOT_FSTYPE_LEN);	/* 	 * Now calculate the FAT type (FAT12 vs. FAT16) per a formula 	 * We warn the user when the FSTYPE string (if present) doesn't match 	 * the calculation.	 */        work = dosFsVolIsFat12(bootSec);        if (ERROR == work)            {    	    ERR_MSG(1, "dosFsVolIsFat12 returned ERROR\n", 0,0,0,0,0,0 );    	    goto error;            }    	if (TRUE == work) /* then calculated FAT12 */    	    {	    /* 	     * Check the FSTYPE field in the BPB to ensure the string	     * value matches our calculation.  If not, the we assume	     * the formatter knew what they wanted, and we honor	     * the string value. We look for "FAT12   " or "FAT16   ".	     */	    if ((strcmp ((char *)tmpType, DOS_BOOT_FSTYPE_FAT16)) == 0)	        {    	        pVolDesc->fatType = FAT16;	        printf("WARNING: FAT16 indicated by BPB FSTYPE string, "		       "cluster calculation was FAT12. Honoring string.\n");	        }	    else		{    	        pVolDesc->fatType = FAT12;	    	}    	    }    	else /* we calculated FAT 16 */    	    {	    /* 	     * Check the FSTYPE field in the BPB to ensure the string	     * value matches our calculation.  If not, the we assume	     * the formatter knew what they wanted, and we honor	     * the string value. We look for "FAT12   " or "FAT16   ".	     */	    if ((strcmp ((char *)tmpType, DOS_BOOT_FSTYPE_FAT12)) == 0)	        {    	        pVolDesc->fatType = FAT12;	        printf("WARNING: FAT12 indicated by BPB FSTYPE string, "		       "cluster calculation was FAT16. Honoring string.\n");	        }	    else		{    	        pVolDesc->fatType = FAT16;	    	}    	    }    	/* volume Id and label */    	    	pVolDesc->volIdOff = DOS_BOOT_VOL_ID;    	pVolDesc->volLabOff = DOS_BOOT_VOL_LABEL;    	}    else	/* Use FAT32 because (pVolDesc->secPerFat == 0) */    	{    	pVolDesc->fatType = FAT32;    	    	/* sectors per fat copy */    	    	pVolDesc->secPerFat = DISK_TO_VX_32( bootSec +    					     DOS32_BOOT_SEC_PER_FAT );    	if( pVolDesc->secPerFat == 0 )    	    {    	    dosFsBadBootMsg( 1, DOS32_BOOT_SEC_PER_FAT, 0,                             "(FAT32)", __LINE__ );    	    goto error;    	    }    	    	/* volume Id and label */    	    	pVolDesc->volIdOff = DOS32_BOOT_VOL_ID;    	pVolDesc->volLabOff = DOS32_BOOT_VOL_LABEL;    	}        /*     * count sector number of data area start cluster.     * This value can be corrected later by directory handler, if     * root directory is not stored as regular directory     * in clusters (FAT32), but instead resides contiguously     * ahead first data cluster (FAT12/FAT16)     */    pVolDesc->dataStartSec = pVolDesc->nReservedSecs +    			     pVolDesc->secPerFat * pVolDesc->nFats;        /* volume Id and label */    	    pVolDesc->volId = DISK_TO_VX_32( bootSec + pVolDesc->volIdOff );    bcopy( (char *)bootSec + pVolDesc->volLabOff,    	   (char *)pVolDesc->bootVolLab, DOS_VOL_LABEL_LEN );    *(pVolDesc->bootVolLab + DOS_VOL_LABEL_LEN) = EOS;    	         /* restore base version of boot sector */    if( pVolDesc->bootSecNum != DOS_BOOT_SEC_NUM )    	{    	ERR_MSG( 1, "Try to reclaim original copy of boot sector\n",		0,0,0,0,0,0 );    	if( (pass == 0) &&            (cbioBlkCopy(pVolDesc->pCbio, pVolDesc->bootSecNum,			DOS_BOOT_SEC_NUM, 1 ) == OK) &&    	    (cbioIoctl(pVolDesc->pCbio, 		       CBIO_CACHE_FLUSH, (void *)(-1) ) == OK))    	    {    	    /* remount again */    	    pass ++;    	    pVolDesc->bootSecNum = DOS_BOOT_SEC_NUM;    	    goto boot_get;    	    }   	}    	    /* currently it is enough for starting */        return (OK);    error:	/* some data is inconsistent */    pVolDesc->bootSecNum ++;    if( pVolDesc->bootSecNum < (u_int)DOS_BOOT_SEC_NUM +			       cbioParams.blocksPerTrack )    	{    	/* try to find other boot block copy on next sector */	    	if( pVolDesc->bootSecNum == DOS_BOOT_SEC_NUM + 1 )    	    {    	    ERR_MSG( 1, "Problem finding volume data, trying to "                    "use the next block as boot block.\n",    	    	     0,0,0,0,0,0 );            /*              * SPR#69074 - only look at the next sector, this avoids             * tons of error messages when mounting unformatted device             * when we used to look at the remaining sectors in the track.             */    	    goto boot_get;    	    }    	ERR_MSG( 1, "Ensure this device is formatted and partitions are "                    "properly handled.\n",    	    	     0,0,0,0,0,0 );    	}    if( errnoGet() == OK )    	errnoSet( S_dosFsLib_UNKNOWN_VOLUME_FORMAT );    return ERROR;    } /* dosFsBootSecGet() *//********************************************************************************* dosFsVolIsFat12 - determine if a MSDOS volume is FAT12 or FAT16** This routine is the container for the logic which determines if a * dosFs volume is using FAT12 or FAT16.  Two methods are implemented. * Both methods use information from the volumes boot parameter block* fields found in the boot sector.** The first FAT determination method follows the recommendations outlined* in the Microsoft document:** "Hardware White Paper*  Designing Hardware for Microsoft

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -