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

📄 filecopy.c

📁 [随书类]Dos6.0源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	register 				i; 					/* Loop Indice 						*/
	int						iFile;				/* DOS file handle					*/
	unsigned 				uStatus; 			/* Error status						*/
	struct find_t			Info;
	uStatus = (UINT) ERROR; 					/* Assume may not be successful	*/

#ifdef SYSTEMS_COMPRESSION
	unsigned 				uRead;				/* Count of byte read from file	*/
	struct PACKED_HEADER	Fh;					/* Struct to hold file header 	*/
	struct WIN_HEADER		Wh;					/* Alternate windows file header	*/
	static char 			MagicValue[8] =	{ 'S',	'Z',	  ' ',	  '\x88',
														 '\xf0', '\x27', '\x33', '\xd1' };
#endif

								/* Try to open the file normally and if it fails	*/
								/* try opening the file as a compressed file by 	*/
								/* switching last char of name extension to a '$'	*/

	for ( i = 0; i < 2; i++ )
	{
		if ( (_dos_findfirst( szFile, _A_FINDALL, &Info ) == OK &&
				_dos_open( szFile, ShareAccess, &iFile ) == OK) )
			break;
		szEndChar = strchr( szFile, EOL );				/* Find end of string	*/
		if ( szEndChar != NULL )
			*(szEndChar - 1) = '_';
	}

	if ( i < 2 )												/* See if open was OK	*/
	{
		File->lDestinSize = File->lSourceSize = filelength( iFile );

#ifdef SYSTEMS_COMPRESSION
																/* Read in the file header */
		if ( _dos_read( iFile, &Wh, sizeof( Wh ), &uRead ) == OK &&
			  uRead > 0 )
		{
												/* Need the header in both structures	*/
			memcpy( &Fh, &Wh, sizeof( Wh ) );

											/* Check for a languages group's header	*/
			if ( memcmp( MagicValue, Fh.MagicStr, sizeof(MagicValue)) == OK )
			{
				File->lDestinSize = Fh.lDestinSize;
				File->lRead = File->lUnpacked = (long)sizeof( Fh );
				File->IsPacked = LANGUAGE_COMPRESS;
			}
									/* Now check for a Windows group's header */
			else if ( memcmp( WIN_STR, Fh.MagicStr, sizeof(MagicValue)) == OK )
			{
				File->lDestinSize = Wh.lDestinSize;
				File->lRead = File->lUnpacked = (long)sizeof( Wh );
				File->IsPacked = WINDOWS_COMPRESS;
			}
			uStatus = OK;
		}
#else
        if ((int) (uStatus = WReadHeaderInfo (iFile)) > 0)
          {
            /* This is a compressed file, using APPS compression.  */
            /*   Unfortunately, the file must be decompressed into */
            /*   RAM, as the APPS compression APIs do not have a   */
            /*   method to decompress from a buffer to a file (but */
            /*   it can decompress from a file to a buffer).       */

            File->lDestinSize = LcbCalculateDecompressedLength (iFile, TRUE);
            File->lSourceSize = File->lDestinSize;
            File->IsPacked = TRUE;
            uStatus = OK;
          }
        else
            uStatus = (uStatus == rcNoHeader) ? OK : ERROR;
#endif

		uStatus |= _dos_getftime( iFile, &File->Date, &File->Time );
		uStatus |= _dos_close( iFile );
	}
	return( (uStatus == OK && File->lSourceSize > 0L) ? OK : ERROR );
}

/***************************************************************************/
/* Initializes the copy buffer to max available memory less 20K bytes. If	*/
/* there is less than 5K of memory available for use the program is			*/
/* with a call to FatalError(). The static global pchCpyBuffer is set to	*/
/* point to the successfully allocated buffer a buffer must also be			*/
/* allocate for the unpack functions. This buffer will have to be				*/
/* normalized so the functions can use it with an offset of 0 so 16 must	*/
/* be added to the offset before normalization to allow for this.				*/
/*																									*/
/*	void InitCpyBuffer( void )																*/
/*																									*/
/* ARGUMENTS:	NONE																			*/
/* RETURNS:		void																			*/
/*																									*/
/* GLOBALS:		lBufSize	- Set to size of allocated buffer						*/
/*					pchCpyBuffer - Pointed to allocated buffer						*/
/*					UnPackSeg	- Normalized ptr to an unpack segment area		*/
/*																									*/
/***************************************************************************/

static int InitCpyBuffer( void )
{
	register	iStatus;

	iStatus = ERROR;									/* Error if fails any test 	*/

															/* Allocate an unpack segment	*/

#ifdef SYSTEMS_COMPRESSION
	/*	UnpackArea = GetMemory(UNPACK_BUF_LEN+RING_BUF_LEN+MAX_STR_LEN+100); */
	UnpackArea = halloc( (long)(UNPACK_BUF_LEN + RING_BUF_LEN +MAX_STR_LEN + 100), 1 );
		if ( UnpackArea == (char far *)(NULL) )
			return( iStatus );

	UnpackSeg = NormalizePtr( (char far *)UnpackArea + 16 );
#endif

						/* Find out how much memory we can get */
	Buf.BufLen = GetMaxHugeSize() - MALLOC_RESERVE;

	if ( Buf.BufLen >= MIN_BUF_SIZE )			/* Is there enough memory ?	*/
	{
		Buf.Start = halloc( Buf.BufLen, 1); 	/* Do we allocate it OK 		*/
		if ( Buf.Start != NULL )
		{
			Buf.Next = Buf.Start;					/* Set next free byte			*/
			Buf.BytesFree = Buf.BufLen;			/* Set number of bytes free	*/
			iStatus = OK;								/* Passed all tests				*/
		}
	}
	return( iStatus );
}

/***************************************************************************/
/* Walks throught the array of file structures and writes out each file 	*/
/* or a portition of each file that resides in the copy buffer.				*/
/* 																								*/
/* int BufFlush( void )																		*/
/* 																								*/
/* ARGUMENTS:	void																			*/
/* RETURN:		int		- OK if no error												*/
/* 																								*/
/* Return status will reflect the status of the last file written. This 	*/
/*	will be a signal to the BufCopyFile() to abort the current file being	*/
/* copied and go to the next file.														*/
/***************************************************************************/

static int BufFlush( void )
{
	char						*szFile;
	int						iFile;
	int						iStatus;

	long						lToWrite;
	long						lWritten;
	struct MULT_FILES 	*ThisFile;
	struct find_t			Info;


	DisplayFileStatus( "", CLEAR );
	szFile = GetMemory( MAX_PATH_LEN );		/* Allocate a path buffer			*/
	Buf.Next = Buf.Start;						/* Reset ptr to begining of buf	*/

											/* Loop until all files are checked */
	for ( iStatus = OK, ThisFile = File;
			ThisFile->Name.Source != NULL;
			ThisFile++ )
	{
		BuildPath( szFile, ThisFile->Drive.Destin, ThisFile->Path.Destin,
					  ThisFile->Name.Destin );

		if ( ThisFile->lUnpacked < ThisFile->lSourceSize )
		{
			iStatus = ERROR;
			lToWrite = ThisFile->lRead - ThisFile->lUnpacked;

			DispInsertUserDisk( ThisFile->UserDisk, ThisFile->Drive.Destin );
			DisplayFileStatus( ThisFile->Name.Destin, WRITE );

			_dos_setfileattr( szFile, _A_NORMAL );

			if ( (_dos_findfirst( szFile, _A_FINDALL, &Info ) == OK &&
				   _dos_open( szFile, O_RDWR, &iFile ) == OK)||
				  _dos_creat( szFile, 0, &iFile ) == OK )
			{
				if ( (lWritten = WriteFile( iFile, ThisFile, lToWrite )) != -1L )
				{
					iStatus = OK;
					ThisFile->lUnpacked += lToWrite;
					ThisFile->lWritten += lWritten;

					if ( ThisFile->lWritten == ThisFile->lDestinSize )
					{			
						chsize( iFile, ThisFile->lDestinSize );
						_dos_setftime( iFile, ThisFile->Date, ThisFile->Time );
					}
				}

				iStatus |= (int)_dos_close( iFile );
			}
		}

		if ( iStatus != OK ||
			  (ThisFile->lRead == ThisFile->lSourceSize &&
				ThisFile->lWritten != ThisFile->lDestinSize) )
		{
			if (gfCompressedDiskInstall)
			{
				gfCompressedDiskIsFull = TRUE;
				FreeMemory (szFile);				/* Free the path buffer 			*/
				return (ERROR);
			}
			else
			{
				ProcessCopyError( ParseFileName( szFile ), ERR_WRITING );
				ThisFile->lSourceSize = 0L;	/* If error set file size to 0	*/
				ThisFile->lDestinSize = 0L;
			}
		}

		if ( ThisFile->lSourceSize == 0L )	/* If source size == 0 we had	an	*/
			remove( szFile );						/* error so delete destin file	*/
	}

	Buf.BytesFree = Buf.BufLen;				/* Reset number of bytes free 	*/
	Buf.Next = Buf.Start;						/* Reset ptr to begining of buf	*/
	FreeMemory( szFile );						/* Free the path buffer 			*/

	DisplayFileStatus( "", CLEAR );
	return( iStatus );
}

/***************************************************************************/
/* Writes out the part of a file in the copy buffer with checking for		*/
/* using UnPack() or BigReadWrite() depending on whether the file is a		*/
/* packed file or not.																		*/
/* 																								*/
/* static long WriteFile( int iFile, struct MULT_FILES *ThisFile, 			*/
/* 							  long lToWrite ) 											*/
/* 																								*/
/* ARGUMENTS:	iFile 	- Open DOS file handle, file pointer must be set	*/
/* 							  to position for start of read or write				*/
/* 				ThisFile - Structure describing the file being written		*/
/* 				lToWrite	- Number of bytes in the copy buffer to write out	*/
/* RETURN:		long		- Number of bytes written to output file or -1L if */
/* 							  and error was detected.									*/
/*																									*/
/***************************************************************************/

static long WriteFile( int iFile, struct MULT_FILES *ThisFile, long lToWrite )
{
	long		lWritten;
#ifdef SYSTEMS_COMPRESSION
	int		HeaderLen;
#endif

	lWritten = -1L;								/* Assume there may be an error */

							/* Be sure file is the length it is supposed to be 	*/
							/* and then seek to the offset for the next write		*/

	if ( filelength( iFile ) >= ThisFile->lWritten &&
		  _dos_seek( iFile, ThisFile->lWritten, SEEK_SET ) == ThisFile->lWritten )
	{
#ifdef SYSTEMS_COMPRESSION
		if ( ThisFile->IsPacked )						/* Check for compress file */
		{
								/* If first time for file, initialize ring buffer	*/
			HeaderLen = ThisFile->IsPacked == WINDOWS_COMPRESS ?
							sizeof( struct WIN_HEADER ) :
							sizeof( struct PACKED_HEADER );

			if ( ThisFile->lUnpacked <= HeaderLen )
				ClearRingBuffer( ThisFile->IsPacked );

			lWritten = Unpack( iFile, ThisFile->pchStart, lToWrite );
		}
		else
#endif
            if ( BigReadWrite( iFile, ThisFile->pchStart, lToWrite,
					 WRITE ) == OK )
				lWritten = lToWrite; 						/* written == lToWrite		*/
	}
	return( lWritten );
}

#ifndef SYSTEMS_COMPRESSION


/***************************************************************************/
/* Expands a file directly from file to file without buffering in memory.	*/
/* Used as a performance enhancement when copying large packed files and	*/
/* installing to a hard disk (no disk swaps necessary).							*/
/* 																								*/
/* static long ExpandFile( int iFile, struct MULT_FILES *ThisFile )			*/
/* 																								*/
/* ARGUMENTS:	fhSrc 	- Open DOS file handle, file pointer must be set	*/
/* 							  to start of file (input packed file) 				*/
/* 				ThisFile - Structure describing the file being written		*/
/* RETURN:		long		- Number of bytes written to output file or -1L if */
/* 							  and error was detected.									*/
/*																									*/
/***************************************************************************/

static long ExpandFile( int fhSrc, struct MULT_FILES *ThisFile )
{
	char				*szFile;
	int				iFile;
	int				iStatus;
	long				lWritten;
	struct find_t	Info;

	DisplayFileStatus( "", CLEAR );
	szFile = GetMemory( MAX_PATH_LEN );		/* Allocate a path buffer			*/

	BuildPath( szFile, ThisFile->Drive.Destin, ThisFile->Path.Destin,
				  ThisFile->Name.Destin );

	iStatus = ERROR;

	DisplayFileStatus( ThisFile->Name.Destin, WRITE );

	_dos_setfileattr( szFile, _A_NORMAL );

	if ( (_dos_findfirst( szFile, _A_FINDALL, &Info ) == OK &&
			_dos_open( szFile, O_RDWR, &iFile ) == OK)||
		  _dos_creat( szFile, 0, &iFile ) == OK )
	{
		lWritten = LcbDecompressToFile( fhSrc, iFile, LCBNIL, 0L, FALSE );
		if ( lWritten == ThisFile->lDestinSize )
		{
			iStatus = OK;
			ThisFile->lWritten  = lWritten;
			ThisFile->lUnpacked = ThisFile->lRead = ThisFile->lSourceSize;

			chsize( iFile, ThisFile->lDestinSize );
			_dos_setftime( iFile, ThisFile->Date, ThisFile->Time );

		} else

			lWritten = 0;					/* error, return 0 size 				*/

		iStatus |= (int)_dos_close( iFile );
	}

	if ( iStatus != OK )
	{
		if (gfCompressedDiskInstall)
		{
			gfCompressedDiskIsFull = TRUE;
			FreeMemory (szFile); 			/* Free the path buffer 			*/
			return (ERROR);
		}
		else
		{
			ProcessCopyError( ParseFileName( szFile ), ERR_WRITING );
			ThisFile->lSourceSize = 0L;	/* If error set file size to 0	*/
			ThisFile->lDestinSize = 0L;
		}
	}

	if ( ThisFile->lSourceSize == 0L )	/* If source size == 0 we had an */
		remove( szFile ); 					/* error so delete destin file	*/

	FreeMemory( szFile );						/* Free the path buffer 			*/

	DisplayFileStatus( "", CLEAR );

	return ( lWritten );

}

#endif

⌨️ 快捷键说明

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