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

📄 dbms.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 3 页
字号:

	/* Dispatch the command */
	memcpy( &cmd, &cmdTemplate, sizeof( COMMAND_INFO ) );
	DISPATCH_COMMAND_DBX( cmdClose, cmd, dbmsInfo );
	}

static void performErrorQuery( DBMS_INFO *dbmsInfo )
	{
	static const COMMAND_INFO cmdTemplate = \
		{ DBX_COMMAND_GETERRORINFO, COMMAND_FLAG_NONE, 0, 1 };
	COMMAND_INFO cmd;
	int status;

	assert( isWritePtr( dbmsInfo, sizeof( DBMS_INFO ) ) );

	/* Clear the return values */
	memset( dbmsInfo->errorMessage, 0, MAX_ERRMSG_SIZE );
	dbmsInfo->errorCode = 0;

	/* Dispatch the command */
	memcpy( &cmd, &cmdTemplate, sizeof( COMMAND_INFO ) );
	cmd.strArg[ 0 ] = dbmsInfo->errorMessage;
	cmd.strArgLen[ 0 ] = 0;
	status = DISPATCH_COMMAND_DBX( cmdGetErrorInfo, cmd, dbmsInfo );
	if( cryptStatusOK( status ) )
		{
		dbmsInfo->errorCode = cmd.arg[ 0 ];
		dbmsInfo->errorMessage[ cmd.strArgLen[ 0 ] ] = '\0';
		}
	}

static int performUpdate( DBMS_INFO *dbmsInfo, const char *command,
						  const void *boundData, const int boundDataLength,
						  const time_t boundDate,
						  const DBMS_UPDATE_TYPE updateType )
	{
	static const COMMAND_INFO cmdTemplate = \
		{ DBX_COMMAND_UPDATE, COMMAND_FLAG_NONE, 1, 1 };
	COMMAND_INFO cmd;
	BYTE encodedDate[ 8 ];
	int status;

	assert( isWritePtr( dbmsInfo, sizeof( DBMS_INFO ) ) );
	assert( updateType > DBMS_UPDATE_NONE && \
			updateType < DBMS_UPDATE_LAST );

	/* If we're trying to abort a transaction that was never begun, don't
	   do anything */
	if( updateType == DBMS_UPDATE_ABORT && \
		!( dbmsInfo->flags & DBMS_FLAG_UPDATEACTIVE ) )
		return( CRYPT_OK );

	/* Dispatch the command */
	initQueryData( &cmd, &cmdTemplate, encodedDate, dbmsInfo, command, 
				   boundData, boundDataLength, boundDate, updateType );
	status = DISPATCH_COMMAND_DBX( cmdUpdate, cmd, dbmsInfo );
	if( cryptStatusError( status ) )
		performErrorQuery( dbmsInfo );
	else
		{
		/* If we're starting or ending an update, record the update state */
		if( updateType == DBMS_UPDATE_BEGIN )
			dbmsInfo->flags |= DBMS_FLAG_UPDATEACTIVE;
		if( updateType == DBMS_UPDATE_COMMIT || \
			updateType == DBMS_UPDATE_ABORT )
			dbmsInfo->flags &= ~DBMS_FLAG_UPDATEACTIVE;
		}
	return( status );
	}

static int performStaticUpdate( DBMS_INFO *dbmsInfo, const char *command )
	{
	return( performUpdate( dbmsInfo, command, NULL, 0, 0,
						   DBMS_UPDATE_NORMAL ) );
	}

static int performQuery( DBMS_INFO *dbmsInfo, const char *command,
						 char *data, int *dataLength, const char *queryData,
						 const int queryDataLength, const time_t queryDate,
						 const DBMS_CACHEDQUERY_TYPE queryEntry, 
						 const DBMS_QUERY_TYPE queryType )
	{
	static const COMMAND_INFO cmdTemplate = \
		{ DBX_COMMAND_QUERY, COMMAND_FLAG_NONE, 2, 1 };
	COMMAND_INFO cmd;
	BYTE encodedDate[ 8 ];
	int argIndex, status;

	assert( isWritePtr( dbmsInfo, sizeof( DBMS_INFO ) ) );
	assert( ( data == NULL && dataLength == NULL ) || \
			isWritePtr( data, 16 ) );
	assert( ( queryData == NULL && queryDataLength == 0 ) || \
			( queryDataLength > 0 && \
			  isReadPtr( queryData, queryDataLength ) ) );
	assert( DBMS_CACHEDQUERY_NONE >= 0 && \
			queryEntry < DBMS_CACHEDQUERY_LAST );
	assert( queryType > DBMS_QUERY_NONE && queryType < DBMS_QUERY_LAST );

	/* Additional state checks: If we're starting a new query or performing
	   a point query there can't already be one active, and if we're 
	   continuing or cancelling an existing query there has to be one 
	   already active */
	assert( ( ( queryType == DBMS_QUERY_START || \
				queryType == DBMS_QUERY_CHECK || \
				queryType == DBMS_QUERY_NORMAL ) && \
			  !( dbmsInfo->flags & DBMS_FLAG_QUERYACTIVE ) ) ||
			( ( queryType == DBMS_QUERY_CONTINUE || \
				queryType == DBMS_QUERY_CANCEL ) && \
			  ( dbmsInfo->flags & DBMS_FLAG_QUERYACTIVE ) ) );

	/* Clear return value */
	if( data != NULL )
		{
		memset( data, 0, 16 );
		*dataLength = 0;
		}

	/* Dispatch the command */
	argIndex = initQueryData( &cmd, &cmdTemplate, encodedDate, dbmsInfo, 
							  command, queryData, queryDataLength, 
							  queryDate, queryType );
	cmd.arg[ 1 ] = queryEntry;
	cmd.strArg[ argIndex ] = data;
	cmd.strArgLen[ argIndex ] = 0;
	cmd.noStrArgs = argIndex + 1;
	status = DISPATCH_COMMAND_DBX( cmdQuery, cmd, dbmsInfo );
	if( cryptStatusError( status ) )
		{
		performErrorQuery( dbmsInfo );
		return( status );
		}

	/* Update the state information based on the query we've just 
	   performed */
	if( queryType == DBMS_QUERY_START  )
		dbmsInfo->flags |= DBMS_FLAG_QUERYACTIVE;
	if( queryType == DBMS_QUERY_CANCEL )
		dbmsInfo->flags &= ~DBMS_FLAG_QUERYACTIVE;
	if( dataLength != NULL )
		{
		*dataLength = cmd.strArgLen[ argIndex ];
		if( *dataLength <= 0 || *dataLength > MAX_QUERY_RESULT_SIZE )
			{
			assert( NOTREACHED );
			memset( data, 0, 16 );
			*dataLength = 0;
			return( CRYPT_ERROR_BADDATA );
			}
		}
	return( CRYPT_OK );
	}

static int performStaticQuery( DBMS_INFO *dbmsInfo, const char *command,
							   const DBMS_CACHEDQUERY_TYPE queryEntry, 
							   const DBMS_QUERY_TYPE queryType )
	{
	return( performQuery( dbmsInfo, command, NULL, NULL, NULL, 0, 0, 
						  queryEntry, queryType ) );
	}
#else

/* Database access functions */

static int openDatabase( DBMS_INFO *dbmsInfo, const char *name,
						 const int options, int *featureFlags )
	{
	DBMS_STATE_INFO *dbmsStateInfo = dbmsInfo->stateInfo;
	int status;

	assert( isWritePtr( dbmsInfo, sizeof( DBMS_INFO ) ) );
	assert( isReadPtr( name, 2 ) );
	assert( isWritePtr( featureFlags, sizeof( int ) ) );

	/* Clear return value */
	*featureFlags = DBMS_HAS_NONE;

	status = dbmsInfo->openDatabaseBackend( dbmsStateInfo, name, options, 
											featureFlags );
	if( cryptStatusError( status ) )
		return( status );

	/* Make long-term information returned as a back-end interface-specific 
	   feature flags persistent if necessary */
	if( *featureFlags & DBMS_HAS_BINARYBLOBS )
		dbmsInfo->flags |= DBMS_FLAG_BINARYBLOBS;

	return( status );
	}

static void closeDatabase( DBMS_INFO *dbmsInfo )
	{
	DBMS_STATE_INFO *dbmsStateInfo = dbmsInfo->stateInfo;

	assert( isWritePtr( dbmsInfo, sizeof( DBMS_INFO ) ) );

	dbmsInfo->closeDatabaseBackend( dbmsStateInfo );
	}

static void performErrorQuery( DBMS_INFO *dbmsInfo )
	{
	DBMS_STATE_INFO *dbmsStateInfo = dbmsInfo->stateInfo;

	assert( isWritePtr( dbmsInfo, sizeof( DBMS_INFO ) ) );

	/* Clear the return values */
	memset( dbmsInfo->errorMessage, 0, MAX_ERRMSG_SIZE );
	dbmsInfo->errorCode = 0;

	dbmsInfo->performErrorQueryBackend( dbmsStateInfo, &dbmsInfo->errorCode, 
										dbmsInfo->errorMessage );
	}

static int performUpdate( DBMS_INFO *dbmsInfo, const char *command,
						  const void *boundData, const int boundDataLength,
						  const time_t boundDate,
						  const DBMS_UPDATE_TYPE updateType )
	{
	DBMS_STATE_INFO *dbmsStateInfo = dbmsInfo->stateInfo;
	int status;

	assert( isWritePtr( dbmsInfo, sizeof( DBMS_INFO ) ) );
	assert( updateType > DBMS_UPDATE_NONE && \
			updateType < DBMS_UPDATE_LAST );

	/* If we're trying to abort a transaction that was never begun, don't
	   do anything */
	if( updateType == DBMS_UPDATE_ABORT && \
		!( dbmsInfo->flags & DBMS_FLAG_UPDATEACTIVE ) )
		return( CRYPT_OK );

	/* Process the update */
	status = dbmsInfo->performUpdateBackend( dbmsStateInfo, command, 
											 boundData, boundDataLength,
											 boundDate, updateType );
	if( cryptStatusError( status ) )
		performErrorQuery( dbmsInfo );
	else
		{
		/* If we're starting or ending an update, record the update state */
		if( updateType == DBMS_UPDATE_BEGIN )
			dbmsInfo->flags |= DBMS_FLAG_UPDATEACTIVE;
		if( updateType == DBMS_UPDATE_COMMIT || \
			updateType == DBMS_UPDATE_ABORT )
			dbmsInfo->flags &= ~DBMS_FLAG_UPDATEACTIVE;
		}
	return( status );
	}

static int performStaticUpdate( DBMS_INFO *dbmsInfo, const char *command )
	{
	return( performUpdate( dbmsInfo, command, NULL, 0, 0,
						   DBMS_UPDATE_NORMAL ) );
	}

static int performQuery( DBMS_INFO *dbmsInfo, const char *command,
						 char *data, int *dataLength, const char *queryData,
						 const int queryDataLength, const time_t queryDate,
						 const DBMS_CACHEDQUERY_TYPE queryEntry, 
						 const DBMS_QUERY_TYPE queryType )
	{
	DBMS_STATE_INFO *dbmsStateInfo = dbmsInfo->stateInfo;
	int status;

	assert( isWritePtr( dbmsInfo, sizeof( DBMS_INFO ) ) );
	assert( ( data == NULL && dataLength == NULL ) || \
			isWritePtr( data, MAX_QUERY_RESULT_SIZE ) );
	assert( ( queryData == NULL && queryDataLength == 0 ) || \
			( queryDataLength > 0 && \
			  isReadPtr( queryData, queryDataLength ) ) );
	assert( DBMS_CACHEDQUERY_NONE >= 0 && \
			queryEntry < DBMS_CACHEDQUERY_LAST );
	assert( queryType > DBMS_QUERY_NONE && queryType < DBMS_QUERY_LAST );

	/* Additional state checks: If we're starting a new query or performing
	   a point query there can't already be one active, and if we're 
	   continuing or cancelling an existing query there has to be one 
	   already active */
	assert( ( ( queryType == DBMS_QUERY_START || \
				queryType == DBMS_QUERY_CHECK || \
				queryType == DBMS_QUERY_NORMAL ) && \
			  !( dbmsInfo->flags & DBMS_FLAG_QUERYACTIVE ) ) ||
			( ( queryType == DBMS_QUERY_CONTINUE || \
				queryType == DBMS_QUERY_CANCEL ) && \
			  ( dbmsInfo->flags & DBMS_FLAG_QUERYACTIVE ) ) );

	/* Clear return value */
	if( data != NULL )
		{
		memset( data, 0, 16 );
		*dataLength = 0;
		}

	/* Process the query */
	status = dbmsInfo->performQueryBackend( dbmsStateInfo, command, data, 
											dataLength, queryData, 
											queryDataLength, queryDate,
											queryEntry, queryType );
	if( cryptStatusError( status ) )
		{
		performErrorQuery( dbmsInfo );
		return( status );
		}

	/* Sanity-check the result data from the back-end */
	if( dataLength != NULL && \
		( *dataLength <= 0 || *dataLength > MAX_QUERY_RESULT_SIZE ) )
		{
		assert( NOTREACHED );
		memset( data, 0, 16 );
		*dataLength = 0;
		return( CRYPT_ERROR_BADDATA );
		}

	/* Update the state information based on the query we've just 
	   performed */
	if( queryType == DBMS_QUERY_START  )
		dbmsInfo->flags |= DBMS_FLAG_QUERYACTIVE;
	if( queryType == DBMS_QUERY_CANCEL )
		dbmsInfo->flags &= ~DBMS_FLAG_QUERYACTIVE;
	return( CRYPT_OK );
	}

static int performStaticQuery( DBMS_INFO *dbmsInfo, const char *command,
							   const DBMS_CACHEDQUERY_TYPE queryEntry, 
							   const DBMS_QUERY_TYPE queryType )
	{
	return( performQuery( dbmsInfo, command, NULL, NULL, NULL, 0, 0, 
						  queryEntry, queryType ) );
	}
#endif /* USE_RPCAPI */

/****************************************************************************
*																			*
*								Utility Routines							*
*																			*
****************************************************************************/

/* The escape char used to escape potentially dangerous values in SQL
   strings */

#define	SQL_ESCAPE	'\''

/* Format input parameters into SQL queries suitable for submission to the
   DBMS back-end, with assorted safety checks of the query data.  One
   additional check that we could do is to try and explicitly strip SQL
   keywords from queries, but this is somewhat problematic because apart
   from the usual trickery (e.g. embedding one SQL keyword inside another
   so that stripping SELECT from SELSELECTECT will still leave the outer
   SELECT) there are also any number of backend-specific custom keywords 
   and ways of escaping keywords that we can't know about and therefore
   can't easily strip.  Since we're using parameterised queries wherever
   possible the following stripping is really just belt-and-suspenders 
   security */

void dbmsFormatSQL( char *buffer, const char *format, ... )
	{

⌨️ 快捷键说明

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