/*
*	ﾊﾞｯﾁﾌｧｲﾙ用ﾄﾞﾗｲﾌﾞﾁｪｯｸﾌﾟﾛｸﾞﾗﾑ
*
*	Usage: drivechk ﾊﾟｽ名 [ﾘﾄﾗｲ回数]
*/

#include <stdio.h>			/*  printf()	*/
#include <string.h>			/*  strlen()	*/
#include <stdlib.h>			/*  atoi()		*/
#include <dos.h>			/*  _dos*(),_harderr()	*/
#include <signal.h>			/*	signal()	*/
#include <time.h>			/*	clock(),CLK_TCK	*/

#define	FERR_CRITICAL		(-1)
unsigned	Criticalerr = FERR_CRITICAL ;		/*  致命的ｴﾗｰ処理ｺｰﾄﾞ	*/

static void far critical_handler( unsigned devcode,unsigned code,unsigned dev )
/*===========================================================================
*	致命的ｴﾗｰのﾏｽｸ処理用ﾊﾝﾄﾞﾗ
===========================================================================*/
{
	devcode = dev = 0 ;							/*  ﾉｰﾁｪｯｸ(手抜き)		*/
	Criticalerr = code ;
	_hardresume( _HARDERR_FAIL ) ;				/*  中断(ﾌｧﾝｸｼｮﾝｺｰﾙ失敗)*/
}

static int drivechk( char *path )
/*===========================================================================
*	ﾄﾞﾗｲﾌﾞﾁｪｯｸ
*	< IN  >	: path	ﾄﾞﾗｲﾌﾞ名を含むﾊﾟｽ名
*	< RET >	: ｴﾗｰｺｰﾄﾞを返す.
*			: =0	正常終了
*			: =1	ﾄﾞﾗｲﾌﾞ変更不可
===========================================================================*/
{
	unsigned	ndrv ;
	struct find_t	dta ;
	unsigned	drvno, chkdrvno, nowdrv ;
	int		ret ;

	Criticalerr = FERR_CRITICAL ;
	ret = 0 ;
	_dos_getdrive( &nowdrv ) ;
	if ( strlen( path ) ) {						/*  ﾄﾞﾗｲﾌﾞ移動			*/
		if ( path[0] >= 'a' && path[0] <= 'z' ) path[0] -= ' ' ;
		drvno = path[0] - '@' ;
		_dos_setdrive( drvno,&ndrv ) ;
		_dos_getdrive( &chkdrvno ) ;
		_dos_findfirst( "*.*",_A_NORMAL,&dta ) ;
		if ( drvno != chkdrvno ) ret = 1 ;
	}
	_dos_setdrive( nowdrv,&ndrv ) ;
	if ( Criticalerr != FERR_CRITICAL ) ret = 1 ;

	return ( ret ) ;
}

void wait( int cnt )
/*===========================================================================
*	指定された時間停止する.
*	< IN  >	: cnt	待ち時間(1/100秒単位)
===========================================================================*/
{
	double	wait, elaps ;
	clock_t st=clock() ;

	wait = (double)cnt / 100.0L ;
	do {
		elaps = (double)( clock() - st ) ;
		if ( elaps < 0.0L ) elaps *= -1.0L ;
		elaps /= (double)CLK_TCK ;
	} while ( elaps < wait ) ;
}

int main( int ac,char *av[] )
/*===========================================================================
*	ﾒｲﾝ
===========================================================================*/
{
	register int	ret, cnt ;
	int		chkcnt=0 ;

	/*  INT23h,INT24hのﾏｽｸ処理
	--------------------------- */
	signal( SIGINT,SIG_IGN ) ;
	_harderr( critical_handler ) ;

	if ( ac > 1 ) {								/*  引数あり			*/
		if ( ac > 2 ) chkcnt = atoi( av[2] ) ;
		chkcnt++ ;
		if ( chkcnt < 1 ) chkcnt = 1 ;
		for ( cnt=0; cnt<chkcnt; cnt++ ) {
			ret = drivechk( av[1] ) ;
			if ( !ret ) break ;
			printf( "\a" ) ;
			wait( 1 ) ;							/*  1/100 sec wait		*/
		}
		printf( "ドライブチェック : " ) ;
		printf( ret ? "ＮＧ！\n" : "ＯＫ.\n" ) ;
		if ( Criticalerr != FERR_CRITICAL )
			printf( "致命的エラー発生 : error=%d(%02Xh)\n",Criticalerr,\
															Criticalerr ) ;
		return ( ret ) ;
	} else {									/*  引数なし			*/
		printf( "Usage: drivechk パス名 [試行回数]\n" ) ;
		printf( "       試行回数の省略値は, 0 です.\n" ) ;
		return ( 0 ) ;
	}
}

