📄 dosfsfmtlib.c
字号:
/* total sector count */ if( (cbioParams.cbio_nBlocks & ~0xffff ) == 0 ) { VX_TO_DISK_16( cbioParams.cbio_nBlocks, pBoot + DOS_BOOT_NSECTORS); } else { if( bytesPerBlk < 64 ) /* can not do with 32 byte sectors */ goto _done_; VX_TO_DISK_16( 0, pBoot + DOS_BOOT_NSECTORS); VX_TO_DISK_32( cbioParams.cbio_nBlocks, pBoot + DOS_BOOT_LONG_NSECTORS); } if( pConf->nResrvd >= 32 ) backupBootSec = 6 ; else if( pConf->nResrvd >= 2 ) backupBootSec = pConf->nResrvd -1 ; if( pConf->fatType == _FAT32 ) { pBoot [DOS32_BOOT_SIGNATURE] = DOS_EXT_BOOT_SIG; VX_TO_DISK_16( 0, pBoot + DOS_BOOT_SEC_PER_FAT ); VX_TO_DISK_32( pConf->secPerFat, pBoot + DOS32_BOOT_SEC_PER_FAT ); VX_TO_DISK_16( 0, pBoot + DOS32_BOOT_EXT_FLAGS ); VX_TO_DISK_16( 0 /* XXX-? */, pBoot + DOS32_BOOT_FS_VERSION ); VX_TO_DISK_32( 2 /* MUST */, pBoot + DOS32_BOOT_ROOT_START_CLUST); VX_TO_DISK_16( 1 /* MUST */, pBoot + DOS32_BOOT_FS_INFO_SEC ); VX_TO_DISK_16( backupBootSec, pBoot + DOS32_BOOT_BOOT_BKUP ); VX_TO_DISK_32( pConf->volSerial, pBoot + DOS32_BOOT_VOL_ID); bcopy( pConf->volLabel, (char *) pBoot + DOS32_BOOT_VOL_LABEL, DOS_VOL_LABEL_LEN ); bcopy( DOS_BOOT_SYSID_FAT32, (char *)pBoot + DOS32_BOOT_FS_TYPE, DOS_SYS_ID_LEN ); /* "FAT32 " */ if( ! preserve ) { pBoot [ DOS32_BOOT_BIOS_DRV_NUM ] = 0x80; /* assume hard */ } } else /* FAT 16 or FAT 12 */ { /* from offset 0x24 in FAT12/16 have other meaning in FAT32 */ /* indicate extended boot sector fields in use */ pBoot [DOS_BOOT_SIG_REC] = DOS_EXT_BOOT_SIG; VX_TO_DISK_32( pConf->nHidden, pBoot + DOS_BOOT_NHIDDEN_SECS); VX_TO_DISK_32( pConf->volSerial, pBoot + DOS_BOOT_VOL_ID); VX_TO_DISK_16( pConf->secPerFat, pBoot + DOS_BOOT_SEC_PER_FAT ); bcopy( pConf->volLabel, (char *) pBoot + DOS_BOOT_VOL_LABEL, DOS_VOL_LABEL_LEN ); /* Add file system type to offset 0x36, later DOS versions do this */ /* FAT12 */ if (pConf->fatType == _FAT12) { bcopy (DOS_BOOT_FSTYPE_FAT12, (char *) pBoot + DOS_BOOT_FSTYPE_ID, DOS_BOOT_FSTYPE_LEN); } /* FAT16 */ if (pConf->fatType == _FAT16) { bcopy (DOS_BOOT_FSTYPE_FAT16, (char *) pBoot + DOS_BOOT_FSTYPE_ID, DOS_BOOT_FSTYPE_LEN); } if( ! preserve ) { pBoot [ DOS_BOOT_DRIVE_NUM ] = (pConf->fatType == _FAT12) ? 0x00: 0x80 ; /* floppy or hard */ } } /* write the backup boot block */ if( backupBootSec != NONE ) if( cbioBlkRW( cbio_dev, backupBootSec , 1, (addr_t)pBoot, CBIO_WRITE, NULL ) == ERROR ) goto _done_; /* now write the real boot block */ if( cbioBlkRW( cbio_dev, DOS_BOOT_SEC_NUM , 1, (addr_t)pBoot, CBIO_WRITE, NULL ) == ERROR ) goto _done_; /* Done */ stat = OK ;_done_: if( pBoot != bootBlockBuffer ) free( pBoot ); return( stat ); }/******************************************************************************** * dosFsVolFormat - format an MS-DOS compatible volume** This utility routine performs the initialization of file system data* structures on a disk. It supports FAT12 for small disks, FAT16 for* medium size and FAT32 for large volumes.* The <device> argument may be either a device name known to the I/O* system, or a dosFsLib Volume descriptor or a CBIO device handle.** The <opt> argument is a bit-wise or'ed combination of options controlling the* operation of this routine as follows:** .IP DOS_OPT_DEFAULT * If the current volume boot block is reasonably intact, use existing* parameters, else calculate parameters based only on disk size, possibly* reusing only the volume label and serial number.* * .IP DOS_OPT_PRESERVE* Attempt to preserve the current volume parameters even if they seem to* be somewhat unreliable.* * .IP DOS_OPT_BLANK * Disregard the current volume parameters, and calculate new parameters* based only on disk size.** .IP DOS_OPT_QUIET* Do not produce any diagnostic output during formatting.** .IP DOS_OPT_FAT16* Format the volume with FAT16 format even if the disk is larger then * 2 Gbytes, which would normally be formatted with FAT32.** .IP DOS_OPT_FAT32* Format the volume with FAT32, even if the disk is smaller then * 2 Gbytes, but is larger then 512 Mbytes.** .IP DOS_OPT_VXLONGNAMES* Format the volume to use Wind River proprietary case-sensitive Long* File Names. Note that this format is incompatible with any other* implementation of the MS-DOS file system.** .LP* The third argument, <pPromptFunc> is an optional pointer to a function* that may interactively prompt the user to change any of the* modifiable volume parameters before formatting:** .CS* void formatPromptFunc( DOS_VOL_CONFIG *pConfig );* .CE** The <*pConfig> structure upon entry to formatPromptFunc() will contain* the initial volume parameters, some of which can be changed before it* returns. <pPromptFunc> should be NULL if no interactive prompting is* required.** COMPATIBILITY** Although this routine tries to format the disk to be* compatibile with Microsoft implementations of the FAT and FAT32* file systems, there may be differences which are not under WRS* control. For this reason, it is highly recommended that any* disks which are expected to be interchanged between vxWorks and* Windows should be formatted under Windows to provide the best* interchangeability. The WRS implementation is more flexible,* and should be able to handle the differences when formatting is* done on Windows, but Windows implementations may not be able to* handle minor differences between their implementation and ours.** AVAILABILITY* This function is an optional part of the MS-DOS file system,* and may be included in a target system if it is required to* be able to format new volumes.** RETURNS: OK or ERROR if was unable to format the disk.*/STATUS dosFsVolFormat ( void * device, /* device name or volume or CBIO pointer */ int opt, /* bit-wise or'ed options */ FUNCPTR pPromptFunc /* interactive parameter change callback */ ) { DOS_VOL_CONFIG cfg, cfgOld ; CBIO_DEV_ID cbio_dev ; char * pTail; STATUS stat = ERROR ; BOOL preserve ; CBIO_PARAMS cbioParams; /* figure out what kind of device handle we got, * and extract the CBIO pointer */ if( NULL == cbioDevVerify((CBIO_DEV_ID) device, TRUE)) { /* see if the device is a VOL pointer */ if( ((DOS_VOLUME_DESC *) device)->magic != DOS_FS_MAGIC ) { void * pTmp ; /* see if this is a device name */ pTmp = iosDevFind( device, &pTail ); if( (pTmp == NULL) || (pTail == device) ) { errno = S_objLib_OBJ_ID_ERROR; return ERROR; } else if( ((DOS_VOLUME_DESC *) pTmp)->magic != DOS_FS_MAGIC ) { errno = S_objLib_OBJ_ID_ERROR; return ERROR; } cbio_dev = ((DOS_VOLUME_DESC *)pTmp)->pCbio ; } else { cbio_dev = ((DOS_VOLUME_DESC *)device)->pCbio ; } } else cbio_dev = device ; /* make double sure that we have a CBIO handle */ if( NULL == cbioDevVerify(cbio_dev, TRUE )) { errno = S_objLib_OBJ_ID_ERROR; return ERROR; } bzero( (caddr_t) &cfg, sizeof(cfg)); bzero( (caddr_t) &cfgOld, sizeof(cfgOld)); /* take ownership of the device */ if( ERROR == cbioLock (cbio_dev, WAIT_FOREVER)) return ERROR; if( cbioIoctl( cbio_dev, CBIO_RESET, 0) != OK ) goto _done_; if( O_RDONLY == cbioModeGet(cbio_dev)) { errno = S_dosFsLib_READ_ONLY ; goto _done_; } /* Get CBIO device parameters */ if (ERROR == cbioParamsGet (cbio_dev, &cbioParams)) { return (ERROR); } /* set hidden to sectors per track for hard disk */ /* * TODO - nHidden should be the same as the Relative Sector * field in the MS partition table. This is not being done. * This is typically equal to sectors per track actually. */ if (36 < cbioParams.cbio_blksPerTrack) /* 36=2.88 floppy*/ { if ((block_t)cbioParams.cbio_offset <= (block_t)cbioParams.cbio_blksPerTrack) { cfgOld.nHidden = cbioParams.cbio_offset; cfg.nHidden = cbioParams.cbio_offset; } else { cfgOld.nHidden = cbioParams.cbio_blksPerTrack; cfg.nHidden = cbioParams.cbio_blksPerTrack; } } else { cfgOld.nHidden = 0; cfg.nHidden = 0; } stat = dosFsFmtReadBootBlock( cbio_dev, &cfgOld ); if((opt & DOS_OPT_QUIET) == 0) { printf("Retrieved old volume params with %%%d confidence:\n", stat ); dosFsFmtShow(&cfgOld); } switch (opt & 0x3 ) { default: /* preserve if well structured boot block uncovered */ if( stat < 90 ) { cfg.volSerial = cfgOld.volSerial ; bcopy(cfgOld.volLabel, cfg.volLabel, sizeof(cfg.volLabel)) ; preserve = FALSE ; } else { cfg = cfgOld ; preserve = TRUE ; } break ; case DOS_OPT_PRESERVE: /* preserve if not totally corrupt */ if( stat < 50 ) { cfg.volSerial = cfgOld.volSerial ; bcopy(cfgOld.volLabel, cfg.volLabel, sizeof(cfg.volLabel)) ; preserve = FALSE ; } else { cfg = cfgOld ; preserve = TRUE ; } break ; case DOS_OPT_BLANK: /* never preserve */ cfg.volSerial = cfgOld.volSerial ; bcopy(cfg.volLabel, cfgOld.volLabel, sizeof(cfgOld.volLabel)) ; preserve = FALSE ; break ; } if( opt & DOS_OPT_FAT32 ) cfg.fatType = _FAT32 ; else if( opt & DOS_OPT_FAT16 ) cfg.fatType = _FAT16 ; stat = dosFsFmtAutoParams( &cfg, cbioParams.cbio_nBlocks, cbioParams.cbio_bytesPerBlk, opt ); if( pPromptFunc != NULL ) { /* interactive prompting */ (void) (*pPromptFunc)( &cfg ); stat = dosFsFmtAutoParams( &cfg, cbioParams.cbio_nBlocks, cbioParams.cbio_bytesPerBlk, opt ); } if((opt & DOS_OPT_QUIET) == 0) { printf("Disk with %ld sectors of %d bytes will be formatted with:\n", cbioParams.cbio_nBlocks, cbioParams.cbio_bytesPerBlk ); dosFsFmtShow(&cfg); } if(stat != OK) { printErr("dosFsVolFormat: bad format parameters, errno = %#x\n", errno ); goto _done_; } stat = dosFsFmtVolInit( cbio_dev, &cfg, preserve, opt ); /* flush and invalidate cache immediately */ stat |= cbioIoctl( cbio_dev, CBIO_CACHE_INVAL, 0) ; if(stat != OK) { printErr("dosFsVolFormat: format failed, errno=%#x\n", errno ); } cbioRdyChgdSet (cbio_dev, TRUE); /* force re-mount */_done_: cbioUnlock (cbio_dev) ; return stat ; }/********************************************************************************* dosFsFmtLibInit - initialize the MS-DOS formatting library** This function is called to optionally enable the formatting* functionality from dosFsLib.** SEE ALSO: dosFsLib** NOMANUAL*/void dosFsFmtLibInit( void ) { dosFsVolFormatRtn = dosFsVolFormat; }#ifdef __unused__ /********************************************************************************* dosFsFmtTest - UNITEST CODE** NOMANUAL*/void dosFsFmtTest( int size) { DOS_VOL_CONFIG cfg; ULONG i, k ; STATUS stat ; if( size != 0 ) { i = size ; bzero((caddr_t) &cfg, sizeof(cfg)); stat = dosFsFmtAutoParams( &cfg, i, 512, 0) ; dosFsFmtShow( &cfg ); if( stat == ERROR ) perror("dosFsFmtAutoParams"); return; } i = 100 ; for(k=0; k< 1000; k++ ) { bzero((caddr_t) &cfg, sizeof(cfg)); i += rand() ; stat = dosFsFmtAutoParams( &cfg, i, 512, 0) ; dosFsFmtShow( &cfg ); if( stat == ERROR ) { perror("dosFsFmtAutoParams"); return; } } }#endif /* __unused__ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -