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

📄 file.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 5 页
字号:

	REQUIRES( pathMaxLen > 8 && pathMaxLen < MAX_INTLENGTH );
	REQUIRES( fileNameLen > 0 && fileNameLen < MAX_INTLENGTH );
	REQUIRES( ( ( option == BUILDPATH_CREATEPATH || \
				  option == BUILDPATH_GETPATH ) && fileName != NULL ) || \
			  ( option == BUILDPATH_RNDSEEDFILE && fileName == NULL ) );

	/* Make sure that the open fails if we can't build the path */
	*path = '\0';

	/* Make sure that the path buffer meets the minimum-length
	   requirements */
	REQUIRES( pathMaxLen >= 64 );

	/* Build the path to the configuration file if necessary.  We assume that
	   we're on the correct drive */
	strlcpy_s( path, pathMaxLen, "\\cryptlib\\" );

	/* If we're being asked to create the cryptlib directory and it doesn't
	   already exist, create it now */
	if( option == BUILDPATH_CREATEPATH && fjisdir( path ) == 0 )
		{
		/* The directory doesn't exist, try and create it */
		if( fjmkdir( path ) < 0 )
			return( CRYPT_ERROR_OPEN );
		}

	/* Add the filename to the path */
	return( appendFilename( path, pathMaxLen, pathLen, fileName, 
							fileNameLen, option ) );
	}

/****************************************************************************
*																			*
*							uC/OS-II File Stream Functions					*
*																			*
****************************************************************************/

#elif defined( __UCOSII__ )

/* Open/close a file stream */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int sFileOpen( INOUT STREAM *stream, IN_STRING const char *fileName, 
			   IN_FLAGS( FILE ) const int mode )
	{
	static const char *modes[] = { MODE_READ, MODE_READ,
								   MODE_WRITE, MODE_READWRITE };
	const char *openMode;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( fileName != NULL );
	
	REQUIRES( mode != 0 );

	/* Initialise the stream structure */
	memset( stream, 0, sizeof( STREAM ) );
	stream->type = STREAM_TYPE_FILE;
	if( ( mode & FILE_FLAG_RW_MASK ) == FILE_FLAG_READ )
		stream->flags = STREAM_FLAG_READONLY;
	openMode = modes[ mode & FILE_FLAG_RW_MASK ];

	/* If we're trying to write to the file, check whether we've got
	   permission to do so */
	if( ( mode & FILE_FLAG_WRITE ) && fileReadonly( fileName ) )
		return( CRYPT_ERROR_PERMISSION );

	/* Try and open the file */
	stream->pFile = FS_FOpen( fileName, openMode );
	if( stream->pFile == NULL )
		{
		const FS_i16 errNo = FS_FError();

		/* Return what we can in the way of an error message.  Curiously
		   uC/FS doesn't provide an indicator for common errors like file
		   not found, although it does provide strange indicators like
		   FS_ERR_CLOSE, an error occurred while calling FS_FClose() */
		return( ( errNo == FS_ERR_DISKFULL ) ? \
					CRYPT_ERROR_OVEWFLOW : \
				( errNo == FS_ERR_READONLY ) ? \
					CRYPT_ERROR_PERMISSION : CRYPT_ERROR_OPEN );
		}

	return( CRYPT_OK );
	}

RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int sFileClose( INOUT STREAM *stream )
	{
	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	
	REQUIRES( stream->type == STREAM_TYPE_FILE );

	/* Close the file and clear the stream structure */
	FS_FClose( stream->pFile );
	zeroise( stream, sizeof( STREAM ) );

	return( CRYPT_OK );
	}

/* Read/write a block of data from/to a file stream */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
int fileRead( INOUT STREAM *stream, 
			  OUT_BUFFER( length, *bytesRead ) void *buffer, 
			  IN_LENGTH const int length, 
			  OUT_LENGTH_Z int *bytesRead )
	{
	int byteCount;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( buffer, length ) );
	assert( isWritePtr( bytesRead, sizeof( int ) ) );

	REQUIRES( stream->type == STREAM_TYPE_FILE );
	REQUIRES( length > 0 && length < MAX_INTLENGTH );

	/* Clear return value */
	*bytesRead = 0;

	if( ( byteCount = FS_Read( stream->pFile, buffer, length ) ) < 0 )
		return( sSetError( stream, CRYPT_ERROR_READ ) );
	*bytesRead = byteCount;

	return( CRYPT_OK );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int fileWrite( INOUT STREAM *stream, 
			   IN_BUFFER( length ) const void *buffer, 
			   IN_LENGTH const int length )
	{
	int bytesWritten;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isReadPtr( buffer, length ) );

	REQUIRES( stream->type == STREAM_TYPE_FILE );
	REQUIRES( length > 0 && length < MAX_INTLENGTH );

	if( ( bytesWritten = FS_Write( stream->pFile, buffer, length ) ) < 0 || \
		bytesWritten != length )
		return( sSetError( stream, CRYPT_ERROR_WRITE ) );
	return( CRYPT_OK );
	}

/* Commit data in a file stream to backing storage */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int fileFlush( INOUT STREAM *stream )
	{
	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	
	REQUIRES( stream->type == STREAM_TYPE_FILE );

	/* There is an IOCTL to flush all buffers (for all files) to the backing
	   store, but it's no supported in all drivers and seems a bit excessive
	   for this case */
	return( CRYPT_OK );
	}

/* Change the read/write position in a file */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int fileSeek( INOUT STREAM *stream, IN_LENGTH_Z const long position )
	{
	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	
	REQUIRES( stream->type == STREAM_TYPE_FILE );
	REQUIRES( position >= 0 && position < MAX_INTLENGTH );

	if( FS_FSeek( stream->pFile, position, FS_SEEK_SET ) < 0 )
		return( sSetError( stream, CRYPT_ERROR_READ ) );
	return( CRYPT_OK );
	}

/* Check whether a file is writeable */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
BOOLEAN fileReadonly( IN_STRING const char *fileName )
	{
	FS_U8 fileAttr;

	assert( fileName != NULL );

	if( ( fileAttr = FS_GetFileAttributes( fileName ) ) == 0xFF )
		return( TRUE );

	return( ( fileAttr & FS_ATTR_READONLY ) ? TRUE : FALSE );
	}

/* File deletion functions: Wipe a file from the current position to EOF,
   and wipe and delete a file (although it's not terribly rigorous).
   Vestigia nulla retrorsum */

static void eraseFile( const STREAM *stream, long position, long length )
	{
	assert( isReadPtr( stream, sizeof( STREAM ) ) );
	
	REQUIRES_V( stream->type == STREAM_TYPE_FILE );
	REQUIRES_V( position >= 0 && position < MAX_INTLENGTH );
	REQUIRES_V( length > 0 && length < MAX_INTLENGTH );

	/* Wipe everything past the current position in the file */
	while( length > 0 )
		{
		MESSAGE_DATA msgData;
		BYTE buffer[ ( BUFSIZ * 2 ) + 8 ];
		int bytesToWrite = min( length, BUFSIZ * 2 );

		/* We need to make sure that we fill the buffer with random data for
		   each write, otherwise compressing filesystems will just compress
		   it to nothing */
		setMessageData( &msgData, buffer, bytesToWrite );
		krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_GETATTRIBUTE_S,
						 &msgData, CRYPT_IATTRIBUTE_RANDOM_NONCE );

		if( FS_Write( stream->pFile, buffer, bytesToWrite ) < 0 )
			break;	/* An error occurred while writing, exit */
		length -= bytesToWrite;
		}

	fjchsize( stream->pFile, position );
	}

STDC_NONNULL_ARG( ( 1 ) ) \
void fileClearToEOF( const STREAM *stream )
	{
	int length, position;

	assert( isReadPtr( stream, sizeof( STREAM ) ) );
	
	REQUIRES_V( stream->type == STREAM_TYPE_FILE );

	/* Wipe everything past the current position in the file */
	if( ( length = FS_GetFileSize( fileName ) ) < 0 )
		return;
	if( ( position = FS_FTell( stream->pFile ) ) < 0 )
		return;
	length -= position;
	if( length <= 0 )
		return;	/* Nothing to do, exit */
	eraseFile( stream, position, length );
	}

STDC_NONNULL_ARG( ( 1 ) ) \
void fileErase( IN_STRING const char *fileName )
	{
	STREAM stream;
	int length, status;

	assert( fileName != NULL );

	if( ( length = FS_GetFileSize( fileName ) ) < 0 )
		return;

	/* Try and open the file so that we can erase it.  If this fails, the
	   best that we can do is a straight unlink */
	status = sFileOpen( &stream, fileName,
						FILE_FLAG_READ | FILE_FLAG_WRITE | \
						FILE_FLAG_EXCLUSIVE_ACCESS );
	if( cryptStatusError( status ) )
		{
		remove( fileName );
		return;
		}

	/* Determine the size of the file and erase it */
	eraseFile( &stream, 0, length );

	/* Reset the file's attributes and delete it */
	sFileClose( &stream );
	FS_SetFileAttributes( stream.pFile, FS_ATTR_ARCHIVE );
	FS_SetFileTime( stream.pFile, 0 );
	FS_Remove( fileName );
	}

/* Build the path to a file in the cryptlib directory */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4 ) ) \
int fileBuildCryptlibPath( OUT_BUFFER( pathMaxLen, pathLen ) char *path, 
						   IN_LENGTH_SHORT const int pathMaxLen, 
						   OUT_LENGTH_SHORT_Z int *pathLen,
						   IN_BUFFER( fileNameLen ) const char *fileName, 
						   IN_LENGTH_SHORT const int fileNameLen,
						   IN_ENUM( BUILDPATH_OPTION ) \
						   const BUILDPATH_OPTION_TYPE option )
	{
	assert( isWritePtr( path, pathMaxLen ) );
	assert( isWritePtr( pathLen, sizeof( int ) ) );
	assert( isReadPtr( fileName, fileNameLen ) );

	REQUIRES( pathMaxLen > 8 && pathMaxLen < MAX_INTLENGTH );
	REQUIRES( fileNameLen > 0 && fileNameLen < MAX_INTLENGTH );
	REQUIRES( ( ( option == BUILDPATH_CREATEPATH || \
				  option == BUILDPATH_GETPATH ) && fileName != NULL ) || \
			  ( option == BUILDPATH_RNDSEEDFILE && fileName == NULL ) );

	/* Make sure that the open fails if we can't build the path */
	*path = '\0';

	/* Make sure that the path buffer meets the minimum-length
	   requirements */
	REQUIRES( pathMaxLen >= 64 );

	/* Build the path to the configuration file if necessary.  We assume that
	   we're on the correct drive */
	strlcpy_s( path, pathMaxLen, "\\cryptlib\\" );

	/* If we're being asked to create the cryptlib directory and it doesn't
	   already exist, create it now */
	if( option == BUILDPATH_CREATEPATH )
		{
		FS_DIR dirInfo;

		if( ( dirInfo = FS_OpenDir( path ) ) != NULL )
			FSCloseDir( dirInfo );
		else
			{
			/* The directory doesn't exist, try and create it */
			if( FS_MkDir( path ) < 0 )
				return( CRYPT_ERROR_OPEN );
			}
		}

	/* Add the filename to the path */
	return( appendFilename( path, pathMaxLen, pathLen, fileName, 
							fileNameLen, option ) );
	}

/****************************************************************************
*																			*
*							uITRON File Stream Functions					*
*																			*
****************************************************************************/

/* See the comment in str_file.h for uITRON file handling */

#elif defined( __ITRON__ )

/* Open/close a file stream */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int sFileOpen( INOUT STREAM *stream, IN_STRING const char *fileName, 
			   IN_FLAGS( FILE ) const int mode )
	{
	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( fileName != NULL );

	REQUIRES( mode != 0 );

	/* Initialise the stream structure */
	memset( stream, 0, sizeof( STREAM ) );
	stream->type = STREAM_TYPE_FILE;
	if( ( mode & FILE_FLAG_RW_MASK ) == FILE_FLAG_READ )
		stream->flags = STREAM_FLAG_READONLY;

	/* If we're trying to write to the file, check whether we've got
	   permission to do so */
	if( ( mode & FILE_FLAG_WRITE ) && fileReadonly( fileName ) )
		return( CRYPT_ERROR_PERMISSION );

	/* Try and open the file */
	return( CRYPT_ERROR_OPEN );
	}

RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int sFileClose( INOUT STREAM *stream )
	{
	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	
	REQUIRES( stream->type == STREAM_TYPE_FILE );

	/* Close the file and clear the stream structure */
	zeroise( stream, sizeof( STREAM ) );

	return( CRYPT_OK );
	}

/* Read/write a block of data from/to a file stream */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
int fileRead( INOUT STREAM *stream, 
			  OUT_BUFFER( length, *bytesRead ) void *buffer, 
			  IN_LENGTH const int length, 
			  OUT_LENGTH_Z int *bytesRead )
	{
	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( buffer, length ) );
	assert( isWritePtr( bytesRead, sizeof( int ) ) );

	REQUIRES( stream->type == STREAM_TYPE_FILE );
	REQUIRES( length > 0 && length < MAX_INTLENGTH );

	/* Clear return value */
	*bytesRead = 0;

	return( sSetError( stream, CRYPT_ERROR_READ ) );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int fileWrite( INOUT STREAM *stream, 
			   IN_BUFFER( length ) const void *buffer, 
			   IN_LENGTH const int length )
	{
	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isReadPtr( buffer, length ) );

⌨️ 快捷键说明

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