📄 dosfsfmtlib.c
字号:
* * .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 cbioDev = NULL; STATUS stat = ERROR; char * pTail; BOOL preserve; CBIO_PARAMS cbioParams; /* * Determine what type of device handle we were passed, * and extract the CBIO pointer. */ /* NULL is presumed to be an invalid device */ if (NULL == device) { errno = S_cbioLib_INVALID_CBIO_DEV_ID; return (ERROR); } /* * check for 'device' being a valid DOS_VOLUME_DESC_ID or a CBIO_DEV_ID * SPR#71720 : Ensure the pointer is aligned before attempting to access * any structure member from it. Avoid exception on SH arch w/DIAB. * cbioDevVerify() will do an alignment check internally. The check * "((DOS_VOLUME_DESC_ID)device)->magic" needs _WRS_ALIGN_CHECK(). */ if (OK == cbioDevVerify ((CBIO_DEV_ID) device)) { /* 'device' is a valid CBIO_DEV_ID */ cbioDev = device; } else if (TRUE == _WRS_ALIGN_CHECK(device, DOS_VOLUME_DESC)) { if (DOS_FS_MAGIC == ((DOS_VOLUME_DESC_ID)device)->magic) { /* * 'device' a valid DOS_VOLUME_DESC_ID, use its cbio ptr * Note that it will be cbioDevVerify()'d again below. */ cbioDev = ((DOS_VOLUME_DESC_ID)device)->pCbio; } } if (NULL == cbioDev) { /* * didn't find anything valid above. Last try an iosDevFind() * to see if 'device' is a character string, an io device name. */#ifdef _WRS_DOSFS2_VXWORKS_AE cbioDev = (CBIO_DEV_ID) iosDevFind((char *) device, (const char **)&pTail );#else cbioDev = (CBIO_DEV_ID) iosDevFind((char *) device, (char **)&pTail );#endif /* _WRS_DOSFS2_VXWORKS_AE */ if( (NULL == cbioDev) || (pTail == device) ) { /* 'device' appears invalid, so we bail out */ errno = S_cbioLib_INVALID_CBIO_DEV_ID; return (ERROR); } if (TRUE == _WRS_ALIGN_CHECK(cbioDev, DOS_VOLUME_DESC)) { if( ((DOS_VOLUME_DESC_ID)cbioDev)->magic != DOS_FS_MAGIC ) { /* 'device' appears invalid, so we bail out */ errno = S_cbioLib_INVALID_CBIO_DEV_ID; return (ERROR); } else { /* * 'cbioDev' is now a valid DOS_VOLUME_DESC_ID, use its CBIO * PTR. Note that it will be cbioDevVerify()'d again below. */ cbioDev = ((DOS_VOLUME_DESC_ID)cbioDev)->pCbio; } } } /* Again, verify that we have a valid CBIO handle */ if( ERROR == cbioDevVerify(cbioDev)) { return (ERROR); } else { /* * SPR#71633: cbioDevVerify() may have set errno * above, but if we made it here, then it doesn't * matter to the user, so we clear any errno. */ errno = 0; } /* clear the DOS_VOL_CONFIG structures */ bzero( (caddr_t) &cfg, sizeof(cfg)); bzero( (caddr_t) &cfgOld, sizeof(cfgOld)); /* take ownership of the device */ if( ERROR == cbioLock (cbioDev, WAIT_FOREVER)) return ERROR; /* RESET the CBIO device */ if( cbioIoctl( cbioDev, CBIO_RESET, 0) != OK ) goto _done_; /* Ensure we can write to this CBIO device */ if( O_RDONLY == cbioModeGet(cbioDev)) { errno = S_dosFsLib_READ_ONLY ; goto _done_; } /* Get the underlying CBIO device parameters */ if (ERROR == cbioParamsGet (cbioDev, &cbioParams)) { stat = ERROR; goto _done_; } /* set hidden to sectors per track for hard disk */ /* * jkf The below is a hack. The boot sectors nHidden field should be * set to the same value as the Relative Sector field in the MS * partition table that defines the location of this volume. This * is not being handled here or in usrFdiskPartCreate. Somehow * usrFdiskPartLib.c and dpartCbio.c, should account for this someday. * The value is also typically equal to the sectors per track value. * Don't like the below code at all, it assumes too much. */ if (36 < cbioParams.blocksPerTrack) /* 36=2.88 floppy*/ { if ((block_t)cbioParams.blockOffset <= (block_t)cbioParams.blocksPerTrack) { cfgOld.nHidden = cbioParams.blockOffset; cfg.nHidden = cbioParams.blockOffset; } else { cfgOld.nHidden = cbioParams.blocksPerTrack; cfg.nHidden = cbioParams.blocksPerTrack; } } else { cfgOld.nHidden = 0; cfg.nHidden = 0; } /* read the existing boot block from the disk. */ stat = dosFsFmtReadBootBlock( cbioDev, &cfgOld ); if((opt & DOS_OPT_QUIET) == 0) { printf("Retrieved old volume params with %%%d confidence:\n", stat ); dosFsFmtShow(&cfgOld); } switch (opt & (DOS_OPT_BLANK | DOS_OPT_PRESERVE)) { 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 < 70 ) { 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 ; } /* forcing FAT32 or FAT16 */ if( opt & DOS_OPT_FAT32 ) cfg.fatType = _FAT32 ; else if( opt & DOS_OPT_FAT16 ) cfg.fatType = _FAT16 ; /* calculate the BPB */ stat = dosFsFmtAutoParams( &cfg, cbioParams.nBlocks, cbioParams.bytesPerBlk, opt ); if( pPromptFunc != NULL ) { /* interactive prompting */ (void) (*pPromptFunc)( &cfg ); stat = dosFsFmtAutoParams( &cfg, cbioParams.nBlocks, cbioParams.bytesPerBlk, opt ); } if((opt & DOS_OPT_QUIET) == 0) { printf("Disk with %ld sectors of %d bytes will be formatted with:\n", cbioParams.nBlocks, (int) cbioParams.bytesPerBlk ); dosFsFmtShow(&cfg); } if(stat != OK) { printErr("dosFsVolFormat: bad format parameters, errno = %#x\n", errno ); goto _done_; } stat = dosFsFmtVolInit( cbioDev, &cfg, preserve, opt ); /* flush and invalidate cache immediately */ stat |= cbioIoctl( cbioDev, CBIO_CACHE_INVAL, 0) ; if(stat != OK) { printErr("dosFsVolFormat: format failed, errno=%#x\n", errno ); } cbioRdyChgdSet (cbioDev, TRUE); /* force re-mount */_done_: cbioUnlock (cbioDev) ; 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 + -