File: SQLInstallerError.c

package info (click to toggle)
unixodbc 2.3.6-0.1
  • links: PTS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 11,476 kB
  • sloc: ansic: 92,148; sh: 11,928; makefile: 1,630; yacc: 969; sql: 1
file content (195 lines) | stat: -rw-r--r-- 6,645 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
/**************************************************
 *
 **************************************************
 * This code was created by Peter Harvey @ CodeByDesign.
 * Released under LGPL 28.JAN.99
 *
 * Contributions from...
 * -----------------------------------------------
 * Peter Harvey		- pharvey@codebydesign.com
 **************************************************/
#include <config.h>
#include <odbcinstext.h>

/*!
 * \brief   Standard installer error.
 */
typedef struct tODBCINSTErrorMsg
{
	int 	nCode;  /*!< error code */
	char *  szMsg;  /*!< error text */
} ODBCINSTErrorMsg;

/*! 
 * \brief   A lookup for all standard installer (odbcinst) error codes and 
 *          corresponding message text.
 *
 *          An odd thing that we do here is that we assume the values of error codes
 *          (ODBC_ERROR_GENERAL_ERR, ODBC_ERROR_INVALID_BUFF_LEN, etc) are in the same
 *          sequence we have layed out here... ascending order starting at 1. We then 
 *          can index into here using the standard error code and get the standard error
 *          text. This is why we have 0,"Filler" in here.
 */
static ODBCINSTErrorMsg aODBCINSTErrorMsgs[] =
{
	{ 0,                                      	"Filler" },
	{ ODBC_ERROR_GENERAL_ERR,					"General installer error" },
	{ ODBC_ERROR_INVALID_BUFF_LEN,				"Invalid buffer length" },
	{ ODBC_ERROR_INVALID_HWND,					"Invalid window handle" },
	{ ODBC_ERROR_INVALID_STR,					"Invalid string" },
	{ ODBC_ERROR_INVALID_REQUEST_TYPE,			"Invalid type of request" },
	{ ODBC_ERROR_COMPONENT_NOT_FOUND,			"Unable to find component name" },
	{ ODBC_ERROR_INVALID_NAME,					"Invalid driver or translator name" },
	{ ODBC_ERROR_INVALID_KEYWORD_VALUE,			"Invalid keyword-value pairs" },
	{ ODBC_ERROR_INVALID_DSN,					"Invalid DSN" },
	{ ODBC_ERROR_INVALID_INF,					"Invalid INF" },
	{ ODBC_ERROR_REQUEST_FAILED,				"General error request failed" },
	{ ODBC_ERROR_INVALID_PATH,					"Invalid install path" },
	{ ODBC_ERROR_LOAD_LIB_FAILED,				"Could not load the driver or translator setup library" },
	{ ODBC_ERROR_INVALID_PARAM_SEQUENCE,		"Invalid parameter sequence" },
	{ ODBC_ERROR_INVALID_LOG_FILE,				"Invalid log file" },
	{ ODBC_ERROR_USER_CANCELED,					"User canceled operation" },
	{ ODBC_ERROR_USAGE_UPDATE_FAILED,			"Could not increment or decrement the component usage count" },
	{ ODBC_ERROR_CREATE_DSN_FAILED,				"Could not create the requested DSN" },
	{ ODBC_ERROR_WRITING_SYSINFO_FAILED,		"Error writing sysinfo" },
	{ ODBC_ERROR_REMOVE_DSN_FAILED,				"Removing DSN failed" },
	{ ODBC_ERROR_OUT_OF_MEM,					"Out of memory" },
	{ ODBC_ERROR_OUTPUT_STRING_TRUNCATED,		"String right truncated" }
};

/*! 
 * \brief   Returns error information from odbcinst.
 * 
 *          All calls to odbcinst, except SQLInstallerError and SQLPostInstallerError, may
 *          post/log messages. An application checks the return value of a call and then
 *          calls SQLInstallerError, as needed, to get any error information.
 *
 *          All calls to odbcinst, except SQLInstallerError and SQLPostInstallerError, will
 *          start by clearing out existing messages.
 *
 * \param   nError          Input. Messages are enumerated starting with 1 as the oldest. The
 *                          ODBC specification states that there are a max 8 messages stored at
 *                          any time but unixODBC may provide more than that.
 * \param   pnErrorCode     Output. The odbcinst error code as per the ODBC specification.
 * \param   pszErrorMsg     Output. The error text. In general this is the error text from
 *                          the ODBC specification but unixODBC may provide an alternate, more
 *                          meaningfull text.
 * \param   nErrorMsgMax    Input. Max chars which can be returned in pszErrorMsg.
 * \param   pnErrorMsg      Output. strlen of error text available to be returned.
 * 
 * \return  RETCODE
 * \retval  SQL_NO_DATA             No data to be returned for nError.
 * \retval  SQL_ERROR               Something went wrong - most likley bad args in call.
 * \retval  SQL_SUCCESS_WITH_INFO   Text was truncated.
 * \retval  SQL_SUCCESS             Error information was returned.
 *
 * \sa      SQLPostInstallerError
 *          ODBCINSTErrorMsg
 */
RETCODE SQLInstallerError( WORD nError, DWORD *pnErrorCode, LPSTR pszErrorMsg, WORD nErrorMsgMax, WORD *pnErrorMsg )
{
    HLOGMSG hLogMsg     = NULL;
    WORD    nErrorMsg   = 0;
    char *  pszText     = NULL;

    /* these are mandatory so... */
	if ( pnErrorCode == NULL || pszErrorMsg == NULL )
		return SQL_ERROR;

    /* this is optional so... */
    if ( !pnErrorMsg )
        pnErrorMsg = &nErrorMsg;

    /* get our message */
	if ( inst_logPeekMsg( nError, &hLogMsg ) != LOG_SUCCESS )
		return SQL_NO_DATA;

    /* return code */
    *pnErrorCode = hLogMsg->nCode;

    /* any custom message has precedence over the standard messages since its probably more meaningfull */
    if ( *(hLogMsg->pszMessage) )
        pszText = hLogMsg->pszMessage;
    else
        pszText = aODBCINSTErrorMsgs[hLogMsg->nCode].szMsg;

    /* how many chars in error text? */
    *pnErrorMsg = strlen( pszText );

    /* are we going to have to truncate the text due to lack of buffer space? */
    if ( *pnErrorMsg > nErrorMsgMax )
    {
        strncpy( pszErrorMsg, pszText, nErrorMsgMax );
        pszErrorMsg[ nErrorMsgMax ] = '\0';
        return SQL_SUCCESS_WITH_INFO;
    }

    /* success without further complications :) */
    strcpy( pszErrorMsg, pszText );
    return SQL_SUCCESS;
}

/*! 
 * \brief   A wide char version of SQLInstallerError.
 * 
 * \sa      SQLInstallerError
 */
SQLRETURN   INSTAPI SQLInstallerErrorW(WORD iError,
                            DWORD   *pfErrorCode,
                            LPWSTR  lpszErrorMsg,
                            WORD    cbErrorMsgMax,
                            WORD    *pcbErrorMsg)
{
	char *msg;
	SQLRETURN ret;
	WORD len;

	if ( lpszErrorMsg ) 
	{
		if ( cbErrorMsgMax > 0 )
		{
			msg = calloc( cbErrorMsgMax + 1, 1 );
		}
		else
		{
			msg = NULL;
		}
	}
	else
	{
		msg = NULL;
	}

	ret = SQLInstallerError( iError, 
							pfErrorCode,
							msg,
							cbErrorMsgMax,
							&len );

	if ( ret == SQL_SUCCESS )
	{
		if ( pcbErrorMsg )
			*pcbErrorMsg = len;

		if ( msg && lpszErrorMsg )
		{
			_single_copy_to_wide( lpszErrorMsg, msg, len + 1 );
		}
	}
	else if ( ret == SQL_SUCCESS_WITH_INFO )
	{
		if ( pcbErrorMsg )
			*pcbErrorMsg = len;

		if ( msg && lpszErrorMsg )
		{
			_single_copy_to_wide( lpszErrorMsg, msg, cbErrorMsgMax );
		}
	}

    if ( msg ) {
        free( msg );
    }

	return ret;
}