INFO.C

//*--------------------------------------------------------------------------------- 
//| ODBC System Administrator
//|
//| This code is furnished on an as-is basis as part of the ODBC SDK and is
//| intended for example purposes only.
//|
//| Title: INFO.C
//| This module contains the functions which handle the Info menu items.
//| This module relies on RESULTS and EXECUTE to
//| This file contains the actual code to execute SQL Statements and
//| display them. This file is dependent on the SA Tool data structures
//| and the independent module RESULTS.
//|
//| NOTE: Due to the timing of this sample, only the 1.0 GetInfo constants
//| are shown. To see all GetInfo constants for a 2.0 driver, use the
//| ODBC Test Tool which comes with this SDK.
//*---------------------------------------------------------------------------------
#include "info.h"
#include "ini.h"
#include "sql.h"
#include "sqlext.h"
#include "stdlib.h"
#include "strings.h"
VSZFile;

//*---------------------------------------------------------------------------------
//| Defines and macros
//*---------------------------------------------------------------------------------
#define MAXNAME 35
#define MAXPARMS 18
#define MAXSQL 300

#define szCOMMA ","
#define szBLANK " "

typedef struct tagNEWPIPE {
HWND hwnd;
HINSTANCE hInst;
char szName[MAXNAME];
BOOL fSuccess;
} NEWPIPE;

//*---------------------------------------------------------------------------------
//| Local Function Prototypes
//*---------------------------------------------------------------------------------
BOOL EXTFUN EditPipeWndProc(HWND hDlg, unsigned msg, WPARAM wParam, LPARAM lParam);
void NewPipe(NEWPIPE FAR * np);
BOOL EXTFUN NewPipeWndProc(HWND hDlg, unsigned msg, WPARAM wParam, LPARAM lParam);
BOOL EXTFUN DoPipeWndProc(HWND hDlg, unsigned msg, WPARAM wParam, LPARAM lParam);
void DoPipe(RESULTSSET FAR * rs, CHILDINFO FAR * ci, LPSTR szPipeName,
int FAR xPipes[], int cbCnt);
void DoPipeByValue(RESULTSSET FAR * rs, CHILDINFO FAR * ci, LPSTR sqlpsql,
LPSTR szparms, int FAR xPipes[], int cbCnt, LPSTR szPipeName);
void PrepareParmList(LPSTR str);
SDWORD RefreshList(HWND hDlg, RESULTSSET FAR * rs, CHILDINFO FAR * ci, int state,
LPSTR szQual, LPSTR szOwner, LPSTR szName, int cbCols);
SDWORD RefreshPipeList(HWND hDlg);


//*---------------------------------------------------------------------------------
//| Global variables
//*---------------------------------------------------------------------------------
extern dCSEG(char) szMSSansSerif[];
extern dCSEG(char) szPIPES[];
extern dCSEG(char) szFONT[];
extern char OutStr[MAXBUFF];
extern dCSEG(char) szVALUE[];

dCSEG(char) szISO92[] = "ISO 92";
dCSEG(char) szXOpen[] = "X/Open";
dCSEG(char) szODBC[] = "ODBC";
dCSEG(char) szDepr[] = "Deprecated";

dCSEG(char) szCore[] = "Core";
dCSEG(char) szLvl1[] = "Level 1";
dCSEG(char) szLvl2[] = "Level 2";

dCSEG(char) szYes[] = "Yes";
dCSEG(char) szNo[] = "No";

dCSEG(char) szODBCFunctions[] = "Functions";
dCSEG(char) szODBCDataSources[] = "Data Sources";
dCSEG(char) szODBCDataTypes[] = "Data Types";
dCSEG(char) szGetInfoTitle[] = "Get Info";
dCSEG(char) szQualifier[] = "Qualifier";
dCSEG(char) szOwner[] = "Owner";
dCSEG(char) szName[] = "Name";
dCSEG(char) szType[] = "Type";
dCSEG(char) szSQL[] = "Sql";
dCSEG(char) szPARMS[] = "Parms";
dCSEG(char) szPARMOPT[] = "ParmOpt";
dCSEG(char) szDELETEOPT[] = "Delete";
dCSEG(char) szBothTypes[] = "'%s','%s'";
dCSEG(char) szOneType[] = "'%s'";
dCSEG(char) szBlank[] = " ";
dCSEG(char) szTABLETYPE[] = "TABLE";
dCSEG(char) szVIEWTYPE[] = "VIEW";
dCSEG(char) szVALUE[] = "value";
dCSEG(char) szADDRESS[] = "address";
dCSEG(char) szDeletePipe[] = "Delete pipe %s?";
dCSEG(char) szEditPipe[] = "Edit Pipe";
dCSEG(char) szDuplicatePipe[] = "Pipe already exists";
dCSEG(char) szInstalled[] = "Installed";
dCSEG(char) szDROPPROCSEMI[] = "Drop Procedure (with semi-colon)";

static char szErrorMsgTitle[] = "Error";



struct {
UWORD fFunction; // Identifier for SQLGetFunctions
LPSTR szLevel; // Conformance Level
int idFunction; // String table identifier for function name
} ODBCFunctions[] = {

// fFunction szLevel idFunction
// ------------------------------- --------------- --------------------------------

// ---- ISO 92 Conformance -----------------------------------
{SQL_API_SQLALLOCHANDLE, (LPSTR)szISO92, idsSQLAllocHandle},
{SQL_API_SQLBINDCOL, (LPSTR)szISO92, idsSQLBindCol},
{SQL_API_SQLCANCEL, (LPSTR)szISO92, idsSQLCancel},
{SQL_API_SQLCLOSECURSOR, (LPSTR)szISO92, idsSQLCloseCursor},
{SQL_API_SQLCOLATTRIBUTE, (LPSTR)szISO92, idsSQLColAttribute},
{SQL_API_SQLCONNECT, (LPSTR)szISO92, idsSQLConnect},
{SQL_API_SQLCOPYDESC, (LPSTR)szISO92, idsSQLCopyDesc},
{SQL_API_SQLDATASOURCES, (LPSTR)szISO92, idsSQLDataSources},
{SQL_API_SQLDESCRIBECOL, (LPSTR)szISO92, idsSQLDescribeCol},
{SQL_API_SQLDISCONNECT, (LPSTR)szISO92, idsSQLDisconnect},
{SQL_API_SQLENDTRAN, (LPSTR)szISO92, idsSQLEndTran},
{SQL_API_SQLEXECDIRECT, (LPSTR)szISO92, idsSQLExecDirect},
{SQL_API_SQLEXECUTE, (LPSTR)szISO92, idsSQLExecute},
{SQL_API_SQLFETCH, (LPSTR)szISO92, idsSQLFetch},
{SQL_API_SQLFETCHSCROLL, (LPSTR)szISO92, idsSQLFetchScroll},
{SQL_API_SQLFREEHANDLE, (LPSTR)szISO92, idsSQLFreeHandle},
{SQL_API_SQLFREESTMT, (LPSTR)szISO92, idsSQLFreeStmt},
{SQL_API_SQLGETCONNECTATTR, (LPSTR)szISO92, idsSQLGetConnectAttr},
{SQL_API_SQLGETCURSORNAME, (LPSTR)szISO92, idsSQLGetCursorName},
{SQL_API_SQLGETDATA, (LPSTR)szISO92, idsSQLGetData},
{SQL_API_SQLGETDESCFIELD, (LPSTR)szISO92, idsSQLGetDescField},
{SQL_API_SQLGETDESCREC, (LPSTR)szISO92, idsSQLGetDescRec},
{SQL_API_SQLGETDIAGFIELD, (LPSTR)szISO92, idsSQLGetDiagField},
{SQL_API_SQLGETDIAGREC, (LPSTR)szISO92, idsSQLGetDiagRec},
{SQL_API_SQLGETFUNCTIONS, (LPSTR)szISO92, idsSQLGetFunctions},
{SQL_API_SQLGETINFO, (LPSTR)szISO92, idsSQLGetInfo},
{SQL_API_SQLGETSTMTATTR, (LPSTR)szISO92, idsSQLGetStmtAttr},
{SQL_API_SQLGETTYPEINFO, (LPSTR)szISO92, idsSQLGetTypeInfo},
{SQL_API_SQLGETSTMTATTR, (LPSTR)szISO92, idsSQLGetStmtAttr},
{SQL_API_SQLNUMRESULTCOLS, (LPSTR)szISO92, idsSQLNumResultCols},
{SQL_API_SQLPREPARE, (LPSTR)szISO92, idsSQLPrepare},
{SQL_API_SQLPUTDATA, (LPSTR)szISO92, idsSQLPutData},
{SQL_API_SQLROWCOUNT, (LPSTR)szISO92, idsSQLRowCount},
{SQL_API_SQLSETCONNECTATTR, (LPSTR)szISO92, idsSQLGetConnectAttr},
{SQL_API_SQLSETCURSORNAME, (LPSTR)szISO92, idsSQLSetCursorName},
{SQL_API_SQLSETDESCFIELD, (LPSTR)szISO92, idsSQLSetDescField},
{SQL_API_SQLSETDESCREC, (LPSTR)szISO92, idsSQLSetDescRec},
{SQL_API_SQLSETENVATTR, (LPSTR)szISO92, idsSQLSetEnvAttr},
{SQL_API_SQLSETSTMTATTR, (LPSTR)szISO92, idsSQLSetStmtAttr},

//---- X/Open Conformance -----------------------------------
{SQL_API_SQLCOLUMNS, (LPSTR)szXOpen, idsSQLColumns},
{SQL_API_SQLGETENVATTR, (LPSTR)szXOpen, idsSQLGetEnvAttr},
{SQL_API_SQLSPECIALCOLUMNS, (LPSTR)szXOpen, idsSQLSpecialColumns},
{SQL_API_SQLSTATISTICS, (LPSTR)szXOpen, idsSQLStatistics},
{SQL_API_SQLTABLES, (LPSTR)szXOpen, idsSQLTables},

//---- ODBC Conformance -------------------------------------
{SQL_API_SQLBINDPARAMETER, (LPSTR)szODBC, idsSQLBindParameter},
{SQL_API_SQLBROWSECONNECT, (LPSTR)szODBC, idsSQLBrowseConnect},
{SQL_API_SQLBULKOPERATIONS, (LPSTR)szODBC, idsSQLBulkOperations},
{SQL_API_SQLCOLUMNPRIVILEGES, (LPSTR)szODBC, idsSQLColumnPrivileges},
{SQL_API_SQLDESCRIBEPARAM, (LPSTR)szODBC, idsSQLDescribeParam},
{SQL_API_SQLDRIVERCONNECT, (LPSTR)szODBC, idsSQLDriverConnect},
{SQL_API_SQLFOREIGNKEYS, (LPSTR)szODBC, idsSQLForeignKeys},
{SQL_API_SQLMORERESULTS, (LPSTR)szODBC, idsSQLMoreResults},
{SQL_API_SQLNATIVESQL, (LPSTR)szODBC, idsSQLNativeSQL},
{SQL_API_SQLNUMPARAMS, (LPSTR)szODBC, idsSQLNumParams},
{SQL_API_SQLPRIMARYKEYS, (LPSTR)szODBC, idsSQLPrimaryKeys},
{SQL_API_SQLPROCEDURECOLUMNS, (LPSTR)szODBC, idsSQLProcedureColumns},
{SQL_API_SQLPROCEDURES, (LPSTR)szODBC, idsSQLProcedures},
{SQL_API_SQLSETPOS, (LPSTR)szODBC, idsSQLSetPos},
{SQL_API_SQLTABLEPRIVILEGES, (LPSTR)szODBC, idsSQLTablePrivileges},

//---- Deprecated ----------------------------------------
{SQL_API_SQLALLOCCONNECT, (LPSTR)szDepr, idsSQLAllocConnect},
{SQL_API_SQLALLOCENV, (LPSTR)szDepr, idsSQLAllocEnv},
{SQL_API_SQLALLOCSTMT, (LPSTR)szDepr, idsSQLAllocStmt},
{SQL_API_SQLBINDPARAM, (LPSTR)szDepr, idsSQLBindParam},
{SQL_API_SQLCOLATTRIBUTES, (LPSTR)szDepr, idsSQLColAttributes},
{SQL_API_SQLERROR, (LPSTR)szDepr, idsSQLError},
{SQL_API_SQLEXTENDEDFETCH, (LPSTR)szDepr, idsSQLExtendedFetch},
{SQL_API_SQLFREECONNECT, (LPSTR)szDepr, idsSQLFreeConnect},
{SQL_API_SQLFREEENV, (LPSTR)szDepr, idsSQLFreeEnv},
{SQL_API_SQLGETCONNECTOPTION, (LPSTR)szDepr, idsSQLGetConnectOption},
{SQL_API_SQLGETSTMTOPTION, (LPSTR)szDepr, idsSQLGetStmtOption},
{SQL_API_SQLPARAMOPTIONS, (LPSTR)szDepr, idsSQLParamOptions},
{SQL_API_SQLSETCONNECTOPTION, (LPSTR)szDepr, idsSQLSetConnectOption},
{SQL_API_SQLSETPARAM, (LPSTR)szDepr, idsSQLSetParam},
{SQL_API_SQLSETSCROLLOPTIONS, (LPSTR)szDepr, idsSQLSetScrollOptions},
{SQL_API_SQLSETSTMTOPTION, (LPSTR)szDepr, idsSQLSetStmtOption},
{SQL_API_SQLTRANSACT, (LPSTR)szDepr, idsSQLTransact},
};


//
// Generic prototype for bitmap and value lists
//
// This structure is used for to locate both bitmap and enumeration values.
// Values may appear in the list in any order. If a value is aliased, the
// second value in an enumeration list will not be found; however, a bitmap
// entry would show both aliases as being set.
//
typedef struct tagINFOSTRUCT {
UDWORD fVal; // Which constant
LPSTR szStr; // Print String
} INFOSTRUCT;
typedef INFOSTRUCT FAR * lpINFOSTRUCT;

//
// This macro is used to build rows of the INFOSTRUCT arrays
// guaranteeing that the "print" string is the same as the
// INFO manifest constant.
//
#define INFO_VALUE_ROW(tag) {tag, #tag}



//
// Structure for SQL_ALTER_DOMAIN
//
static INFOSTRUCT GetInfoAlterDomain[] = {
INFO_VALUE_ROW( SQL_AD_ADD_DOMAIN_CONSTRAINT ),
INFO_VALUE_ROW( SQL_AD_DROP_DOMAIN_CONSTRAINT ),
INFO_VALUE_ROW( SQL_AD_ADD_DOMAIN_DEFAULT ),
INFO_VALUE_ROW( SQL_AD_DROP_DOMAIN_DEFAULT ),
INFO_VALUE_ROW( SQL_AD_ADD_CONSTRAINT_INITIALLY_DEFERRED ),
INFO_VALUE_ROW( SQL_AD_ADD_CONSTRAINT_INITIALLY_IMMEDIATE ),
INFO_VALUE_ROW( SQL_AD_ADD_CONSTRAINT_DEFERRABLE ),
INFO_VALUE_ROW( SQL_AD_ADD_CONSTRAINT_NON_DEFERRABLE ),
};

//
// Structure for SQL_ALTER_TABLE
//
static INFOSTRUCT GetInfoAlterTable[] = {
INFO_VALUE_ROW( SQL_AT_ADD_COLUMN_SINGLE ),
INFO_VALUE_ROW( SQL_AT_ADD_CONSTRAINT ),
INFO_VALUE_ROW( SQL_AT_ADD_COLUMN_DEFAULT ),
INFO_VALUE_ROW( SQL_AT_ADD_COLUMN_COLLATION ),
INFO_VALUE_ROW( SQL_AT_SET_COLUMN_DEFAULT ),
INFO_VALUE_ROW( SQL_AT_DROP_COLUMN_DEFAULT ),
INFO_VALUE_ROW( SQL_AT_DROP_COLUMN_CASCADE ),
INFO_VALUE_ROW( SQL_AT_DROP_COLUMN_RESTRICT ),
INFO_VALUE_ROW( SQL_AT_ADD_TABLE_CONSTRAINT ),
INFO_VALUE_ROW( SQL_AT_DROP_TABLE_CONSTRAINT_CASCADE ),
INFO_VALUE_ROW( SQL_AT_DROP_TABLE_CONSTRAINT_RESTRICT ),
INFO_VALUE_ROW( SQL_AT_CONSTRAINT_NAME_DEFINITION ),
INFO_VALUE_ROW( SQL_AT_CONSTRAINT_INITIALLY_DEFERRED ),
INFO_VALUE_ROW( SQL_AT_CONSTRAINT_INITIALLY_IMMEDIATE ),
INFO_VALUE_ROW( SQL_AT_CONSTRAINT_DEFERRABLE ),
INFO_VALUE_ROW( SQL_AT_CONSTRAINT_NON_DEFERRABLE ),
};

//
// Structure for SQL_ANSI_ASYNC_MODE
//
static INFOSTRUCT GetInfoAsyncMode[] = {
INFO_VALUE_ROW( SQL_AM_NONE ),
INFO_VALUE_ROW( SQL_AM_CONNECTION ),
INFO_VALUE_ROW( SQL_AM_STATEMENT ),
};



//
// Structure for SQL_BATCH_ROW_COUNT
//
static INFOSTRUCT GetInfoBatchRowCount[] = {
INFO_VALUE_ROW( SQL_BRC_ROLLED_UP ),
INFO_VALUE_ROW( SQL_BRC_PROCEDURES ),
INFO_VALUE_ROW( SQL_BRC_EXPLICIT ),
};

//
// Structure for SQL_BATCH_SUPPORT
//
static INFOSTRUCT GetInfoBatchSupport[] = {
INFO_VALUE_ROW( SQL_BS_SELECT_EXPLICIT ),
INFO_VALUE_ROW( SQL_BS_ROW_COUNT_EXPLICIT ),
INFO_VALUE_ROW( SQL_BS_SELECT_PROC ),
INFO_VALUE_ROW( SQL_BS_ROW_COUNT_PROC ),
};

//
// Structure for SQL_BOOKMARK_PERSISTENCE
//
static INFOSTRUCT GetInfoBookmarkPersist[] = {
INFO_VALUE_ROW( SQL_BP_CLOSE ),
INFO_VALUE_ROW( SQL_BP_DELETE ),
INFO_VALUE_ROW( SQL_BP_DROP ),
INFO_VALUE_ROW( SQL_BP_TRANSACTION ),
INFO_VALUE_ROW( SQL_BP_UPDATE ),
INFO_VALUE_ROW( SQL_BP_OTHER_HSTMT ),
};

//
// Structure for SQL_CATALOG_LOCATION
//
static INFOSTRUCT GetInfoCatLocation[] = {
INFO_VALUE_ROW( SQL_CL_START ),
INFO_VALUE_ROW( SQL_CL_END ),
};



//
// Structure for SQL_CATALOG_USAGE
//
static INFOSTRUCT GetInfoCatUsage[] = {
INFO_VALUE_ROW( SQL_CU_DML_STATEMENTS ),
INFO_VALUE_ROW( SQL_CU_PROCEDURE_INVOCATION ),
INFO_VALUE_ROW( SQL_CU_TABLE_DEFINITION ),
INFO_VALUE_ROW( SQL_CU_INDEX_DEFINITION ),
INFO_VALUE_ROW( SQL_CU_PRIVILEGE_DEFINITION ),
};

//
// Structure for SQL_CONCAT_NULL_BEHAVIOR
//
static INFOSTRUCT GetInfoConcat[] = {
INFO_VALUE_ROW( SQL_CB_NULL ),
INFO_VALUE_ROW( SQL_CB_NON_NULL ),
};

//
// Structure for SQL_CONVERT_xxxx
//
static INFOSTRUCT GetInfoConvertTypes[] = {
INFO_VALUE_ROW( SQL_CVT_BIGINT ),
INFO_VALUE_ROW( SQL_CVT_BINARY ),
INFO_VALUE_ROW( SQL_CVT_BIT ),
INFO_VALUE_ROW( SQL_CVT_CHAR ),
INFO_VALUE_ROW( SQL_CVT_DATE ),
INFO_VALUE_ROW( SQL_CVT_DECIMAL ),
INFO_VALUE_ROW( SQL_CVT_DOUBLE ),
INFO_VALUE_ROW( SQL_CVT_FLOAT ),
INFO_VALUE_ROW( SQL_CVT_INTEGER ),
INFO_VALUE_ROW( SQL_CVT_INTERVAL_YEAR_MONTH ),
INFO_VALUE_ROW( SQL_CVT_INTERVAL_DAY_TIME ),
INFO_VALUE_ROW( SQL_CVT_LONGVARBINARY ),
INFO_VALUE_ROW( SQL_CVT_LONGVARCHAR ),
INFO_VALUE_ROW( SQL_CVT_NUMERIC ),
INFO_VALUE_ROW( SQL_CVT_REAL ),
INFO_VALUE_ROW( SQL_CVT_SMALLINT ),
INFO_VALUE_ROW( SQL_CVT_TIME ),
INFO_VALUE_ROW( SQL_CVT_TIMESTAMP ),
INFO_VALUE_ROW( SQL_CVT_TINYINT ),
INFO_VALUE_ROW( SQL_CVT_VARBINARY ),
INFO_VALUE_ROW( SQL_CVT_VARCHAR ),
INFO_VALUE_ROW( SQL_CVT_WCHAR ),
INFO_VALUE_ROW( SQL_CVT_WLONGVARCHAR ),
INFO_VALUE_ROW( SQL_CVT_WVARCHAR ),
};

//
// Structure for SQL_CONVERT_FUNCTIONS
//
static INFOSTRUCT GetInfoConvertFunctions[] = {
INFO_VALUE_ROW( SQL_FN_CVT_CAST ),
INFO_VALUE_ROW( SQL_FN_CVT_CONVERT ),
};

//
// Structure for SQL_CORRELATION_NAME
//
static INFOSTRUCT GetInfoCorrelationName[] = {
INFO_VALUE_ROW( SQL_CN_NONE ),
INFO_VALUE_ROW( SQL_CN_DIFFERENT ),
INFO_VALUE_ROW( SQL_CN_ANY ),
};

//
// Structure for SQL_CREATE_ASSERTION
//
static INFOSTRUCT GetInfoCreateAssertion[] = {
INFO_VALUE_ROW( SQL_CA_CREATE_ASSERTION ),
INFO_VALUE_ROW( SQL_CA_CONSTRAINT_INITIALLY_DEFERRED ),
INFO_VALUE_ROW( SQL_CA_CONSTRAINT_INITIALLY_IMMEDIATE ),
INFO_VALUE_ROW( SQL_CA_CONSTRAINT_DEFERRABLE ),
INFO_VALUE_ROW( SQL_CA_CONSTRAINT_NON_DEFERRABLE ),
};

//
// Structure for SQL_CREATE_CHARACTER_SET
//
static INFOSTRUCT GetInfoCreateCharset[] = {
INFO_VALUE_ROW( SQL_CCS_CREATE_CHARACTER_SET ),
INFO_VALUE_ROW( SQL_CCS_COLLATE_CLAUSE ),
INFO_VALUE_ROW( SQL_CCS_LIMITED_COLLATION ),
};

//
// Structure for SQL_CREATE_COLLATION
//
static INFOSTRUCT GetInfoCreateCollation[] = {
INFO_VALUE_ROW( SQL_CCOL_CREATE_COLLATION ),
};

//
// Structure for SQL_CREATE_DOMAIN
//
static INFOSTRUCT GetInfoCreateDomain[] = {
INFO_VALUE_ROW( SQL_CDO_CREATE_DOMAIN ),
INFO_VALUE_ROW( SQL_CDO_CONSTRAINT ),
INFO_VALUE_ROW( SQL_CDO_DEFAULT ),
INFO_VALUE_ROW( SQL_CDO_COLLATION ),
INFO_VALUE_ROW( SQL_CDO_CONSTRAINT_NAME_DEFINITION ),
INFO_VALUE_ROW( SQL_CDO_CONSTRAINT_INITIALLY_DEFERRED ),
INFO_VALUE_ROW( SQL_CDO_CONSTRAINT_INITIALLY_IMMEDIATE ),
INFO_VALUE_ROW( SQL_CDO_CONSTRAINT_DEFERRABLE ),
INFO_VALUE_ROW( SQL_CDO_CONSTRAINT_NON_DEFERRABLE ),
};

//
// Structure for SQL_CREATE_SCHEMA
//
static INFOSTRUCT GetInfoCreateSchema[] = {
INFO_VALUE_ROW( SQL_CS_CREATE_SCHEMA ),
INFO_VALUE_ROW( SQL_CS_AUTHORIZATION ),
INFO_VALUE_ROW( SQL_CS_DEFAULT_CHARACTER_SET ),
};

//
// Structure for SQL_CREATE_TABLE
//
static INFOSTRUCT GetInfoCreateTable[] = {
INFO_VALUE_ROW( SQL_CT_COMMIT_PRESERVE ),
INFO_VALUE_ROW( SQL_CT_COMMIT_DELETE ),
INFO_VALUE_ROW( SQL_CT_GLOBAL_TEMPORARY ),
INFO_VALUE_ROW( SQL_CT_LOCAL_TEMPORARY ),
INFO_VALUE_ROW( SQL_CT_CONSTRAINT_INITIALLY_DEFERRED ),
INFO_VALUE_ROW( SQL_CT_CONSTRAINT_INITIALLY_IMMEDIATE ),
INFO_VALUE_ROW( SQL_CT_CONSTRAINT_DEFERRABLE ),
INFO_VALUE_ROW( SQL_CT_CONSTRAINT_NON_DEFERRABLE ),
};

//
// Structure for SQL_CREATE_TRANSLATION
//
static INFOSTRUCT GetInfoCreateXlation[] = {
INFO_VALUE_ROW( SQL_CTR_CREATE_TRANSLATION ),
};

//
// Structure for SQL_CREATE_VIEW
//
static INFOSTRUCT GetInfoCreateView[] = {
INFO_VALUE_ROW( SQL_CV_CREATE_VIEW ),
INFO_VALUE_ROW( SQL_CV_CHECK_OPTION ),
INFO_VALUE_ROW( SQL_CV_CASCADED ),
INFO_VALUE_ROW( SQL_CV_LOCAL ),
};

//
// Structure for SQL_CURSOR_COMMIT_BEHAVIOR,
// SQL_CURSOR_ROLLBACK_BEHAVIOR
//
static INFOSTRUCT GetInfoCommit[] = {
INFO_VALUE_ROW( SQL_CB_DELETE ),
INFO_VALUE_ROW( SQL_CB_CLOSE ),
INFO_VALUE_ROW( SQL_CB_PRESERVE ),
};

//
// Structure for SQL_CURSOR_SENSITIVITY
//
static INFOSTRUCT GetInfoCursorSensitiv[] = {
INFO_VALUE_ROW( SQL_INSENSITIVE ),
INFO_VALUE_ROW( SQL_UNSPECIFIED ),
INFO_VALUE_ROW( SQL_SENSITIVE ),
};

//
// Structure for SQL_DEFAULT_TXN_ISOLATION
//
static INFOSTRUCT GetInfoTXNIsolation[] = {
INFO_VALUE_ROW( SQL_TXN_READ_UNCOMMITTED ),
INFO_VALUE_ROW( SQL_TXN_READ_COMMITTED ),
INFO_VALUE_ROW( SQL_TXN_REPEATABLE_READ ),
INFO_VALUE_ROW( SQL_TXN_SERIALIZABLE ),
};

//
// Structure for SQL_*_CURSOR_ATTRIBUTES1
//
static INFOSTRUCT GetInfoCurAttrs1[] = {
INFO_VALUE_ROW( SQL_CA1_NEXT ),
INFO_VALUE_ROW( SQL_CA1_ABSOLUTE ),
INFO_VALUE_ROW( SQL_CA1_RELATIVE ),
INFO_VALUE_ROW( SQL_CA1_BOOKMARK ),
INFO_VALUE_ROW( SQL_CA1_LOCK_NO_CHANGE ),
INFO_VALUE_ROW( SQL_CA1_LOCK_UNLOCK ),
INFO_VALUE_ROW( SQL_CA1_POS_POSITION ),
INFO_VALUE_ROW( SQL_CA1_POS_UPDATE ),
INFO_VALUE_ROW( SQL_CA1_POS_DELETE ),
INFO_VALUE_ROW( SQL_CA1_POS_REFRESH ),
INFO_VALUE_ROW( SQL_CA1_POSITIONED_UPDATE ),
INFO_VALUE_ROW( SQL_CA1_POSITIONED_DELETE ),
INFO_VALUE_ROW( SQL_CA1_SELECT_FOR_UPDATE ),
INFO_VALUE_ROW( SQL_CA1_BULK_ADD ),
INFO_VALUE_ROW( SQL_CA1_BULK_UPDATE_BY_BOOKMARK ),
INFO_VALUE_ROW( SQL_CA1_BULK_DELETE_BY_BOOKMARK ),
INFO_VALUE_ROW( SQL_CA1_BULK_FETCH_BY_BOOKMARK ),
};

//
// Structure for SQL_*_CURSOR_ATTRIBUTES2
//
static INFOSTRUCT GetInfoCurAttrs2[] = {
INFO_VALUE_ROW( SQL_CA2_READ_ONLY_CONCURRENCY ),
INFO_VALUE_ROW( SQL_CA2_LOCK_CONCURRENCY ),
INFO_VALUE_ROW( SQL_CA2_OPT_ROWVER_CONCURRENCY ),
INFO_VALUE_ROW( SQL_CA2_OPT_VALUES_CONCURRENCY ),
INFO_VALUE_ROW( SQL_CA2_SENSITIVITY_ADDITIONS ),
INFO_VALUE_ROW( SQL_CA2_SENSITIVITY_DELETIONS ),
INFO_VALUE_ROW( SQL_CA2_SENSITIVITY_UPDATES ),
INFO_VALUE_ROW( SQL_CA2_MAX_ROWS_SELECT ),
INFO_VALUE_ROW( SQL_CA2_MAX_ROWS_INSERT ),
INFO_VALUE_ROW( SQL_CA2_MAX_ROWS_UPDATE ),
INFO_VALUE_ROW( SQL_CA2_MAX_ROWS_DELETE ),
INFO_VALUE_ROW( SQL_CA2_MAX_ROWS_CATALOG ),
INFO_VALUE_ROW( SQL_CA2_MAX_ROWS_AFFECTS_ALL ),
INFO_VALUE_ROW( SQL_CA2_CRC_EXACT ),
INFO_VALUE_ROW( SQL_CA2_CRC_APPROXIMATE ),
INFO_VALUE_ROW( SQL_CA2_SIMULATE_NON_UNIQUE ),
INFO_VALUE_ROW( SQL_CA2_SIMULATE_TRY_UNIQUE ),
INFO_VALUE_ROW( SQL_CA2_SIMULATE_UNIQUE ),
};

//
// Structure for SQL_DATETIME_LITERALS
//
static INFOSTRUCT GetInfoSQLDateLit[] = {
INFO_VALUE_ROW( SQL_DL_SQL92_DATE ),
INFO_VALUE_ROW( SQL_DL_SQL92_TIME ),
INFO_VALUE_ROW( SQL_DL_SQL92_TIMESTAMP ),
INFO_VALUE_ROW( SQL_DL_SQL92_INTERVAL_YEAR ),
INFO_VALUE_ROW( SQL_DL_SQL92_INTERVAL_MONTH ),
INFO_VALUE_ROW( SQL_DL_SQL92_INTERVAL_DAY ),
INFO_VALUE_ROW( SQL_DL_SQL92_INTERVAL_HOUR ),
INFO_VALUE_ROW( SQL_DL_SQL92_INTERVAL_MINUTE ),
INFO_VALUE_ROW( SQL_DL_SQL92_INTERVAL_SECOND ),
INFO_VALUE_ROW( SQL_DL_SQL92_INTERVAL_YEAR_TO_MONTH ),
INFO_VALUE_ROW( SQL_DL_SQL92_INTERVAL_DAY_TO_HOUR ),
INFO_VALUE_ROW( SQL_DL_SQL92_INTERVAL_DAY_TO_MINUTE ),
INFO_VALUE_ROW( SQL_DL_SQL92_INTERVAL_DAY_TO_SECOND ),
INFO_VALUE_ROW( SQL_DL_SQL92_INTERVAL_HOUR_TO_MINUTE ),
INFO_VALUE_ROW( SQL_DL_SQL92_INTERVAL_HOUR_TO_SECOND ),
INFO_VALUE_ROW( SQL_DL_SQL92_INTERVAL_MINUTE_TO_SECOND ),
};

//
// Structure for SQL_DROP_ASSERTION
//
static INFOSTRUCT GetInfoDropAssertion[] = {
INFO_VALUE_ROW( SQL_DA_DROP_ASSERTION ),
};

//
// Structure for SQL_DROP_CHARACTER_SET
//
static INFOSTRUCT GetInfoDropCharset[] = {
INFO_VALUE_ROW( SQL_DCS_DROP_CHARACTER_SET ),
};

//
// Structure for SQL_DROP_COLLATION
//
static INFOSTRUCT GetInfoDropCollation[] = {
INFO_VALUE_ROW( SQL_DC_DROP_COLLATION ),
};

//
// Structure for SQL_DROP_DOMAIN
//
static INFOSTRUCT GetInfoDropDomain[] = {
INFO_VALUE_ROW( SQL_DD_DROP_DOMAIN ),
INFO_VALUE_ROW( SQL_DD_CASCADE ),
INFO_VALUE_ROW( SQL_DD_RESTRICT ),
};

//
// Structure for SQL_DROP_SCHEMA
//
static INFOSTRUCT GetInfoDropSchema[] = {
INFO_VALUE_ROW( SQL_DS_DROP_SCHEMA ),
INFO_VALUE_ROW( SQL_DS_CASCADE ),
INFO_VALUE_ROW( SQL_DS_RESTRICT ),
};

//
// Structure for SQL_DROP_TABLE
//
static INFOSTRUCT GetInfoDropTable[] = {
INFO_VALUE_ROW( SQL_DT_DROP_TABLE ),
INFO_VALUE_ROW( SQL_DT_CASCADE ),
INFO_VALUE_ROW( SQL_DT_RESTRICT ),
};

//
// Structure for SQL_DROP_TRANSLATION
//
static INFOSTRUCT GetInfoDropXlation[] = {
INFO_VALUE_ROW( SQL_DTR_DROP_TRANSLATION ),
};

//
// Structure for SQL_DROP_VIEW
//
static INFOSTRUCT GetInfoDropView[] = {
INFO_VALUE_ROW( SQL_DV_DROP_VIEW ),
INFO_VALUE_ROW( SQL_DV_CASCADE ),
INFO_VALUE_ROW( SQL_DV_RESTRICT ),
};

//
// Structure for SQL_FILE_USAGE
//
static INFOSTRUCT GetInfoFileUsage[] = {
INFO_VALUE_ROW( SQL_FILE_NOT_SUPPORTED ),
INFO_VALUE_ROW( SQL_FILE_TABLE ),
INFO_VALUE_ROW( SQL_FILE_CATALOG ),
};

//
// Structure for SQL_GETDATA_EXTENSIONS
//
static INFOSTRUCT GetInfoGetdataExt[] = {
INFO_VALUE_ROW( SQL_GD_ANY_COLUMN ),
INFO_VALUE_ROW( SQL_GD_ANY_ORDER ),
INFO_VALUE_ROW( SQL_GD_BLOCK ),
INFO_VALUE_ROW( SQL_GD_BOUND ),
};

//
// Structure for SQL_GROUP_BY
//
static INFOSTRUCT GetInfoGroupBy[] = {
INFO_VALUE_ROW( SQL_GB_NOT_SUPPORTED ),
INFO_VALUE_ROW( SQL_GB_GROUP_BY_EQUALS_SELECT ),
INFO_VALUE_ROW( SQL_GB_GROUP_BY_CONTAINS_SELECT ),
INFO_VALUE_ROW( SQL_GB_NO_RELATION ),
INFO_VALUE_ROW( SQL_GB_COLLATE ),
};

//
// Structure for SQL_INDEX_KEYWORDS
//
static INFOSTRUCT GetInfoIndexKeywords[] = {
INFO_VALUE_ROW( SQL_IK_NONE ),
INFO_VALUE_ROW( SQL_IK_ASC ),
INFO_VALUE_ROW( SQL_IK_DESC ),
INFO_VALUE_ROW( SQL_IK_ALL ),
};

//
// Structure for SQL_INFO_SCHEMA_VIEWS
//
static INFOSTRUCT GetInfoInfoSchemaViews[] = {
INFO_VALUE_ROW( SQL_ISV_ASSERTIONS ),
INFO_VALUE_ROW( SQL_ISV_CHARACTER_SETS ),
INFO_VALUE_ROW( SQL_ISV_CHECK_CONSTRAINTS ),
INFO_VALUE_ROW( SQL_ISV_COLLATIONS ),
INFO_VALUE_ROW( SQL_ISV_COLUMN_DOMAIN_USAGE ),
INFO_VALUE_ROW( SQL_ISV_COLUMN_PRIVILEGES ),
INFO_VALUE_ROW( SQL_ISV_COLUMNS ),
INFO_VALUE_ROW( SQL_ISV_CONSTRAINT_COLUMN_USAGE ),
INFO_VALUE_ROW( SQL_ISV_CONSTRAINT_TABLE_USAGE ),
INFO_VALUE_ROW( SQL_ISV_ASSERTIONS ),
INFO_VALUE_ROW( SQL_ISV_DOMAIN_CONSTRAINTS ),
INFO_VALUE_ROW( SQL_ISV_DOMAINS ),
INFO_VALUE_ROW( SQL_ISV_KEY_COLUMN_USAGE ),
INFO_VALUE_ROW( SQL_ISV_REFERENTIAL_CONSTRAINTS ),
INFO_VALUE_ROW( SQL_ISV_SQL_LANGUAGES ),
INFO_VALUE_ROW( SQL_ISV_TABLE_CONSTRAINTS ),
INFO_VALUE_ROW( SQL_ISV_TABLE_PRIVILEGES ),
INFO_VALUE_ROW( SQL_ISV_TABLES ),
INFO_VALUE_ROW( SQL_ISV_TRANSLATIONS ),

INFO_VALUE_ROW( SQL_ISV_USAGE_PRIVILEGES                   ), 
INFO_VALUE_ROW( SQL_ISV_VIEW_COLUMN_USAGE ),
INFO_VALUE_ROW( SQL_ISV_VIEW_TABLE_USAGE ),
INFO_VALUE_ROW( SQL_ISV_VIEWS ),
};

//
// Structure for SQL_NON_NULLABLE_COLUMNS
//
static INFOSTRUCT GetInfoNonNullCols[] = {
INFO_VALUE_ROW( SQL_NNC_NULL ),
INFO_VALUE_ROW( SQL_NNC_NON_NULL ),
};

//
// Structure for SQL_NULL_COLLATION
//
static INFOSTRUCT GetInfoNullCollation[] = {
INFO_VALUE_ROW( SQL_NC_END ),
INFO_VALUE_ROW( SQL_NC_HIGH ),
INFO_VALUE_ROW( SQL_NC_LOW ),
INFO_VALUE_ROW( SQL_NC_START ),
};

//
// Structure for SQL_PARAM_ARRAY_ROW_COUNTS
//
static INFOSTRUCT GetInfoParamRowCounts[] = {
INFO_VALUE_ROW( SQL_PARC_BATCH ),
INFO_VALUE_ROW( SQL_PARC_NO_BATCH ),
};

//
// Structure for SQL_PARAM_ARRAY_SELECTS
//
static INFOSTRUCT GetInfoParamSelects[] = {
INFO_VALUE_ROW( SQL_PAS_BATCH ),
INFO_VALUE_ROW( SQL_PAS_NO_BATCH ),
INFO_VALUE_ROW( SQL_PAS_NO_SELECT ),
};

//
// Structure for SQL_SCHEMA_USAGE
//
static INFOSTRUCT GetInfoSchemaUsage[] = {
INFO_VALUE_ROW( SQL_SU_DML_STATEMENTS ),
INFO_VALUE_ROW( SQL_SU_PROCEDURE_INVOCATION ),
INFO_VALUE_ROW( SQL_SU_TABLE_DEFINITION ),
INFO_VALUE_ROW( SQL_SU_INDEX_DEFINITION ),
INFO_VALUE_ROW( SQL_SU_PRIVILEGE_DEFINITION ),
};

//
// Structure for SQL_SCROLL_OPTIONS
//
static INFOSTRUCT GetInfoScrollOptions[] = {
INFO_VALUE_ROW( SQL_SO_FORWARD_ONLY ),
INFO_VALUE_ROW( SQL_SO_KEYSET_DRIVEN ),
INFO_VALUE_ROW( SQL_SO_DYNAMIC ),
INFO_VALUE_ROW( SQL_SO_MIXED ),
};

//
// Structure for SQL_SQL_CONFORMANCE
//
static INFOSTRUCT GetInfoSQLConform[] = {
INFO_VALUE_ROW( SQL_SC_SQL92_ENTRY ),
INFO_VALUE_ROW( SQL_SC_FIPS127_2_TRANSITIONAL ),
INFO_VALUE_ROW( SQL_SC_SQL92_FULL ),
INFO_VALUE_ROW( SQL_SC_SQL92_INTERMEDIATE ),
};

//
// Structure for SQL_SQL92_DATETIME_FUNCTIONS
//
static INFOSTRUCT GetInfoS92DatetimeFns[] = {
INFO_VALUE_ROW( SQL_SDF_CURRENT_DATE ),
INFO_VALUE_ROW( SQL_SDF_CURRENT_TIME ),
INFO_VALUE_ROW( SQL_SDF_CURRENT_TIMESTAMP ),
};

//
// Structure for SQL_SQL92_FOREIGN_KEY_DELETE_RULE
//
static INFOSTRUCT GetInfoS92FKeyDelRule[] = {
INFO_VALUE_ROW( SQL_SFKD_CASCADE ),
INFO_VALUE_ROW( SQL_SFKD_NO_ACTION ),
INFO_VALUE_ROW( SQL_SFKD_SET_DEFAULT ),
INFO_VALUE_ROW( SQL_SFKD_SET_NULL ),
};

//
// Structure for SQL_SQL92_FOREIGN_KEY_UPDATE_RULE
//
static INFOSTRUCT GetInfoS92FKeyUpdRule[] = {
INFO_VALUE_ROW( SQL_SFKU_CASCADE ),
INFO_VALUE_ROW( SQL_SFKU_NO_ACTION ),
INFO_VALUE_ROW( SQL_SFKU_SET_DEFAULT ),
INFO_VALUE_ROW( SQL_SFKU_SET_NULL ),
};

//
// Structure for SQL_SQL92_GRANT
//
static INFOSTRUCT GetInfoS92Grant[] = {
INFO_VALUE_ROW( SQL_SG_USAGE_ON_DOMAIN ),
INFO_VALUE_ROW( SQL_SG_USAGE_ON_CHARACTER_SET ),
INFO_VALUE_ROW( SQL_SG_USAGE_ON_COLLATION ),
INFO_VALUE_ROW( SQL_SG_USAGE_ON_TRANSLATION ),
INFO_VALUE_ROW( SQL_SG_WITH_GRANT_OPTION ),
};

//
// Structure for SQL_NUMERIC_FUNCTIONS
//
static INFOSTRUCT GetInfoNumeric[] = {
INFO_VALUE_ROW( SQL_FN_NUM_ABS ),
INFO_VALUE_ROW( SQL_FN_NUM_ACOS ),
INFO_VALUE_ROW( SQL_FN_NUM_ASIN ),
INFO_VALUE_ROW( SQL_FN_NUM_ATAN ),
INFO_VALUE_ROW( SQL_FN_NUM_ATAN2 ),
INFO_VALUE_ROW( SQL_FN_NUM_CEILING ),
INFO_VALUE_ROW( SQL_FN_NUM_COS ),
INFO_VALUE_ROW( SQL_FN_NUM_COT ),
INFO_VALUE_ROW( SQL_FN_NUM_EXP ),
INFO_VALUE_ROW( SQL_FN_NUM_FLOOR ),
INFO_VALUE_ROW( SQL_FN_NUM_LOG ),
INFO_VALUE_ROW( SQL_FN_NUM_MOD ),
INFO_VALUE_ROW( SQL_FN_NUM_RAND ),
INFO_VALUE_ROW( SQL_FN_NUM_PI ),
INFO_VALUE_ROW( SQL_FN_NUM_SIGN ),
INFO_VALUE_ROW( SQL_FN_NUM_SIN ),
INFO_VALUE_ROW( SQL_FN_NUM_SQRT ),
INFO_VALUE_ROW( SQL_FN_NUM_TAN ),
};

//
// Structure for SQL_SQL92_NUMERIC_VALUE_FUNCTIONS
//
static INFOSTRUCT GetInfoS92NumValFns[] = {
INFO_VALUE_ROW( SQL_SNVF_BIT_LENGTH ),
INFO_VALUE_ROW( SQL_SNVF_CHAR_LENGTH ),
INFO_VALUE_ROW( SQL_SNVF_CHARACTER_LENGTH ),
INFO_VALUE_ROW( SQL_SNVF_EXTRACT ),
INFO_VALUE_ROW( SQL_SNVF_OCTET_LENGTH ),
INFO_VALUE_ROW( SQL_SNVF_POSITION ),
};

//
// Structure for SQL_SQL92_PREDICATES
//
static INFOSTRUCT GetInfoS92Predicates[] = {
INFO_VALUE_ROW( SQL_SP_EXISTS ),
INFO_VALUE_ROW( SQL_SP_ISNOTNULL ),
INFO_VALUE_ROW( SQL_SP_ISNULL ),
INFO_VALUE_ROW( SQL_SP_MATCH_FULL ),
INFO_VALUE_ROW( SQL_SP_MATCH_PARTIAL ),
INFO_VALUE_ROW( SQL_SP_MATCH_UNIQUE_FULL ),
INFO_VALUE_ROW( SQL_SP_MATCH_UNIQUE_PARTIAL ),
INFO_VALUE_ROW( SQL_SP_OVERLAPS ),
INFO_VALUE_ROW( SQL_SP_UNIQUE ),
INFO_VALUE_ROW( SQL_SP_LIKE ),
INFO_VALUE_ROW( SQL_SP_IN ),
INFO_VALUE_ROW( SQL_SP_BETWEEN ),
INFO_VALUE_ROW( SQL_SP_COMPARISON ),
INFO_VALUE_ROW( SQL_SP_QUANTIFIED_COMPARISON ),
};

//
// Structure for SQL_SQL92_RELATIONAL_JOIN_OPERATORS
//
static INFOSTRUCT GetInfoS92RelJoinOps[] = {
INFO_VALUE_ROW( SQL_SRJO_CORRESPONDING_CLAUSE ),
INFO_VALUE_ROW( SQL_SRJO_CROSS_JOIN ),
INFO_VALUE_ROW( SQL_SRJO_EXCEPT_JOIN ),
INFO_VALUE_ROW( SQL_SRJO_FULL_OUTER_JOIN ),
INFO_VALUE_ROW( SQL_SRJO_INNER_JOIN ),
INFO_VALUE_ROW( SQL_SRJO_INTERSECT_JOIN ),
INFO_VALUE_ROW( SQL_SRJO_LEFT_OUTER_JOIN ),
INFO_VALUE_ROW( SQL_SRJO_NATURAL_JOIN ),
INFO_VALUE_ROW( SQL_SRJO_RIGHT_OUTER_JOIN ),
INFO_VALUE_ROW( SQL_SRJO_UNION_JOIN ),
};

//
// Structure for SQL_SQL92_REVOKE
//
static INFOSTRUCT GetInfoS92Revoke[] = {
INFO_VALUE_ROW( SQL_SR_USAGE_ON_DOMAIN ),
INFO_VALUE_ROW( SQL_SR_USAGE_ON_CHARACTER_SET ),
INFO_VALUE_ROW( SQL_SR_USAGE_ON_COLLATION ),
INFO_VALUE_ROW( SQL_SR_USAGE_ON_TRANSLATION ),
INFO_VALUE_ROW( SQL_SR_GRANT_OPTION_FOR ),
};

//
// Structure for SQL_SQL92_ROW_VALUE_CONSTRUCTOR
//
static INFOSTRUCT GetInfoS92RowValConstr[] = {
INFO_VALUE_ROW( SQL_SRVC_VALUE_EXPRESSION ),
INFO_VALUE_ROW( SQL_SRVC_NULL ),
INFO_VALUE_ROW( SQL_SRVC_DEFAULT ),
INFO_VALUE_ROW( SQL_SRVC_ROW_SUBQUERY ),
};

//
// Structure for SQL_SQL92_STRING_FUNCTIONS
//
static INFOSTRUCT GetInfoS92StringFns[] = {
INFO_VALUE_ROW( SQL_SSF_CONVERT ),
INFO_VALUE_ROW( SQL_SSF_LOWER ),
INFO_VALUE_ROW( SQL_SSF_UPPER ),
INFO_VALUE_ROW( SQL_SSF_SUBSTRING ),
INFO_VALUE_ROW( SQL_SSF_TRANSLATE ),
INFO_VALUE_ROW( SQL_SSF_TRIM_BOTH ),
INFO_VALUE_ROW( SQL_SSF_TRIM_LEADING ),
INFO_VALUE_ROW( SQL_SSF_TRIM_TRAILING ),
};

//
// Structure for SQL_SQL92_VALUE_EXPRESSIONS
//
static INFOSTRUCT GetInfoS92ValueExprs[] = {
INFO_VALUE_ROW( SQL_SVE_CASE ),
INFO_VALUE_ROW( SQL_SVE_CAST ),
INFO_VALUE_ROW( SQL_SVE_COALESCE ),
INFO_VALUE_ROW( SQL_SVE_NULLIF ),
};

//
// Structure for SQL_SQL92_STANDARD_CLI_CONFORMANCE
//
static INFOSTRUCT GetInfoS92StdCLIConf[] = {
INFO_VALUE_ROW( SQL_SCC_XOPEN_CLI_VERSION1 ),
INFO_VALUE_ROW( SQL_SCC_ISO92_CLI ),
};

//
// Structure for SQL_SUBQUERUIES
//
static INFOSTRUCT GetInfoSubqueries[] = {
INFO_VALUE_ROW( SQL_SQ_CORRELATED_SUBQUERIES ),
INFO_VALUE_ROW( SQL_SQ_COMPARISON ),
INFO_VALUE_ROW( SQL_SQ_EXISTS ),
INFO_VALUE_ROW( SQL_SQ_IN ),
INFO_VALUE_ROW( SQL_SQ_QUANTIFIED ),
};

//
// Structure for SQL_STRING_FUNCTIONS
//
static INFOSTRUCT GetInfoStrings[] = {
INFO_VALUE_ROW( SQL_FN_STR_ASCII ),
INFO_VALUE_ROW( SQL_FN_STR_CHAR ),
INFO_VALUE_ROW( SQL_FN_STR_CONCAT ),
INFO_VALUE_ROW( SQL_FN_STR_INSERT ),
INFO_VALUE_ROW( SQL_FN_STR_LCASE ),
INFO_VALUE_ROW( SQL_FN_STR_LEFT ),
INFO_VALUE_ROW( SQL_FN_STR_LENGTH ),
INFO_VALUE_ROW( SQL_FN_STR_LOCATE ),
INFO_VALUE_ROW( SQL_FN_STR_LTRIM ),
INFO_VALUE_ROW( SQL_FN_STR_REPEAT ),
INFO_VALUE_ROW( SQL_FN_STR_REPLACE ),
INFO_VALUE_ROW( SQL_FN_STR_RIGHT ),
INFO_VALUE_ROW( SQL_FN_STR_RTRIM ),
INFO_VALUE_ROW( SQL_FN_STR_SUBSTRING ),
INFO_VALUE_ROW( SQL_FN_STR_UCASE ),
};

//
// Structure for SQL_SYSTEM_FUNCTIONS
//
static INFOSTRUCT GetInfoSystem[] = {
INFO_VALUE_ROW( SQL_FN_SYS_DBNAME ),
INFO_VALUE_ROW( SQL_FN_SYS_IFNULL ),
INFO_VALUE_ROW( SQL_FN_SYS_USERNAME ),
};

//
// Structure for SQL_TIMEDATE_FUNCTIONS
//
static INFOSTRUCT GetInfoTimeDate[] = {
INFO_VALUE_ROW( SQL_FN_TD_CURDATE ),
INFO_VALUE_ROW( SQL_FN_TD_CURRENT_DATE ),
INFO_VALUE_ROW( SQL_FN_TD_CURRENT_TIME ),
INFO_VALUE_ROW( SQL_FN_TD_CURRENT_TIMESTAMP ),
INFO_VALUE_ROW( SQL_FN_TD_CURTIME ),
INFO_VALUE_ROW( SQL_FN_TD_DAYOFMONTH ),
INFO_VALUE_ROW( SQL_FN_TD_DAYOFWEEK ),
INFO_VALUE_ROW( SQL_FN_TD_DAYOFYEAR ),
INFO_VALUE_ROW( SQL_FN_TD_EXTRACT ),
INFO_VALUE_ROW( SQL_FN_TD_HOUR ),
INFO_VALUE_ROW( SQL_FN_TD_MINUTE ),
INFO_VALUE_ROW( SQL_FN_TD_MONTH ),
INFO_VALUE_ROW( SQL_FN_TD_NOW ),
INFO_VALUE_ROW( SQL_FN_TD_QUARTER ),
INFO_VALUE_ROW( SQL_FN_TD_SECOND ),
INFO_VALUE_ROW( SQL_FN_TD_WEEK ),
INFO_VALUE_ROW( SQL_FN_TD_YEAR ),
};

//
// Structure for SQL_TIMEDATE_ADD_INTERVALS,
// SQL_TIMEDATE_DIFF_INTERVALS,
//
static INFOSTRUCT GetInfoTimeDateIvls[] = {
INFO_VALUE_ROW( SQL_FN_TSI_FRAC_SECOND ),
INFO_VALUE_ROW( SQL_FN_TSI_SECOND ),
INFO_VALUE_ROW( SQL_FN_TSI_MINUTE ),
INFO_VALUE_ROW( SQL_FN_TSI_HOUR ),
INFO_VALUE_ROW( SQL_FN_TSI_DAY ),
INFO_VALUE_ROW( SQL_FN_TSI_WEEK ),
INFO_VALUE_ROW( SQL_FN_TSI_MONTH ),
INFO_VALUE_ROW( SQL_FN_TSI_QUARTER ),
INFO_VALUE_ROW( SQL_FN_TSI_YEAR ),
};

//
// Structure for SQL_ODBC_API_CONFORMANCE
//
static INFOSTRUCT GetInfoAPIConform[] = {
INFO_VALUE_ROW( SQL_OIC_CORE ),
INFO_VALUE_ROW( SQL_OIC_LEVEL1 ),
INFO_VALUE_ROW( SQL_OIC_LEVEL2 ),
};

//
// Structure for SQL_ODBC_SQL_CONFORMANCE
//
static INFOSTRUCT GetInfoODBCSQL[] = {
INFO_VALUE_ROW( SQL_OSC_MINIMUM ),
INFO_VALUE_ROW( SQL_OSC_CORE ),
INFO_VALUE_ROW( SQL_OSC_EXTENDED ),
};

//
// Structure for SQL_IDENTIFIER_CASE
//
static INFOSTRUCT GetInfoIDCase[] = {
INFO_VALUE_ROW( SQL_IC_UPPER ),
INFO_VALUE_ROW( SQL_IC_LOWER ),
INFO_VALUE_ROW( SQL_IC_SENSITIVE ),
INFO_VALUE_ROW( SQL_IC_MIXED ),
};

//
// Structure for SQL_TXN_CAPABLE
//
static INFOSTRUCT GetInfoTxnCapable[] = {
INFO_VALUE_ROW( SQL_TC_NONE ),
INFO_VALUE_ROW( SQL_TC_DML ),
INFO_VALUE_ROW( SQL_TC_DDL_COMMIT ),
INFO_VALUE_ROW( SQL_TC_DDL_IGNORE ),
INFO_VALUE_ROW( SQL_TC_ALL ),
};

//
// Structure for SQL_TXN_ISOLATION_OPTIONS
//
static INFOSTRUCT GetInfoTxnIsoOptions[] = {
INFO_VALUE_ROW( SQL_TXN_READ_UNCOMMITTED ),
INFO_VALUE_ROW( SQL_TXN_READ_COMMITTED ),
INFO_VALUE_ROW( SQL_TXN_REPEATABLE_READ ),
INFO_VALUE_ROW( SQL_TXN_SERIALIZABLE ),
};

//
// Structure for SQL_UNION
//
static INFOSTRUCT GetInfoUnion[] = {
INFO_VALUE_ROW( SQL_U_UNION ),
INFO_VALUE_ROW( SQL_U_UNION_ALL ),
};


//
// The following structure is used to retrieve information about the driver. There
// are 5 types of GetInfo structures:
// INT16 16-bit value
// INT32 32-bit value
// STRVAL String value
// DEXVAL Indexed item (eg: 0-x)
// BITVAL Bit-mask value
//
char szGetInfo[MAXBUFF];
UWORD cb16;
UDWORD cb32;
#define INT16 1
#define INT32 2
#define STRVAL 3
#define DEXVAL 4
#define BITVAL 5

#define INFOROW(name, string, type, addr, varsize, ptr, size) {name, string, type, addr, varsize, ptr, size}

#define INT16_ITEM(name) INFOROW(name, #name, INT16, &cb16, sizeof(cb16), NULL, 0)
#define INT32_ITEM(name) INFOROW(name, #name, INT32, &cb32, sizeof(cb32), NULL, 0)
#define STRNG_ITEM(name) INFOROW(name, #name, STRVAL, szGetInfo, sizeof(szGetInfo), NULL, 0)
#define BIT32_ITEM(name, list) INFOROW(name, #name, BITVAL, &cb32, sizeof(cb32), list, NumItems(list))
#define DEX32_ITEM(name, list) INFOROW(name, #name, DEXVAL, &cb32, sizeof(cb32), list, NumItems(list))


struct {

UWORD fInfoType; // What we're looking for
LPSTR szInfoName; // Print name of the GetInfo item
int fOutType; // string, 16-bit or 32-bit
PTR rgbInfoValue; // Output buffer
SWORD cbInfoMax; // Size of output buffer
void FAR * ptr; // Generic constant structure
int cbNum; // Count of items in ptr

} GetInfo[] = {


// Out Type fInfoType List of Values
// -------- ------------------------- ---------------------------
STRNG_ITEM( SQL_ACCESSIBLE_PROCEDURES ),
STRNG_ITEM( SQL_ACCESSIBLE_TABLES ),
INT16_ITEM( SQL_ACTIVE_ENVIRONMENTS ),
BIT32_ITEM( SQL_ALTER_DOMAIN, GetInfoAlterDomain ),
BIT32_ITEM( SQL_ALTER_TABLE, GetInfoAlterTable ),
DEX32_ITEM( SQL_ASYNC_MODE, GetInfoAsyncMode ),

BIT32_ITEM( SQL_BATCH_ROW_COUNT, GetInfoBatchRowCount ),
BIT32_ITEM( SQL_BATCH_SUPPORT, GetInfoBatchSupport ),
BIT32_ITEM( SQL_BOOKMARK_PERSISTENCE, GetInfoBookmarkPersist ),

DEX32_ITEM( SQL_CATALOG_LOCATION, GetInfoCatLocation ),
STRNG_ITEM( SQL_CATALOG_NAME ),
STRNG_ITEM( SQL_CATALOG_NAME_SEPARATOR ),
STRNG_ITEM( SQL_CATALOG_TERM ),
BIT32_ITEM( SQL_CATALOG_USAGE, GetInfoCatUsage ),
STRNG_ITEM( SQL_COLLATION_SEQ ),
STRNG_ITEM( SQL_COLUMN_ALIAS ),
DEX32_ITEM( SQL_CONCAT_NULL_BEHAVIOR, GetInfoConcat ),
BIT32_ITEM( SQL_CONVERT_BIGINT, GetInfoConvertTypes ),
BIT32_ITEM( SQL_CONVERT_BINARY, GetInfoConvertTypes ),
BIT32_ITEM( SQL_CONVERT_BIT, GetInfoConvertTypes ),
BIT32_ITEM( SQL_CONVERT_CHAR, GetInfoConvertTypes ),
BIT32_ITEM( SQL_CONVERT_DATE, GetInfoConvertTypes ),
BIT32_ITEM( SQL_CONVERT_DECIMAL, GetInfoConvertTypes ),
BIT32_ITEM( SQL_CONVERT_DOUBLE, GetInfoConvertTypes ),
BIT32_ITEM( SQL_CONVERT_FLOAT, GetInfoConvertTypes ),
BIT32_ITEM( SQL_CONVERT_FUNCTIONS, GetInfoConvertTypes ),
BIT32_ITEM( SQL_CONVERT_INTEGER, GetInfoConvertTypes ),
BIT32_ITEM( SQL_CONVERT_LONGVARBINARY, GetInfoConvertTypes ),
BIT32_ITEM( SQL_CONVERT_LONGVARCHAR, GetInfoConvertTypes ),
BIT32_ITEM( SQL_CONVERT_NUMERIC, GetInfoConvertTypes ),
BIT32_ITEM( SQL_CONVERT_REAL, GetInfoConvertTypes ),
BIT32_ITEM( SQL_CONVERT_SMALLINT, GetInfoConvertTypes ),
BIT32_ITEM( SQL_CONVERT_TIME, GetInfoConvertTypes ),
BIT32_ITEM( SQL_CONVERT_TIMESTAMP, GetInfoConvertTypes ),
BIT32_ITEM( SQL_CONVERT_TINYINT, GetInfoConvertTypes ),
BIT32_ITEM( SQL_CONVERT_VARBINARY, GetInfoConvertTypes ),
BIT32_ITEM( SQL_CONVERT_VARCHAR, GetInfoConvertTypes ),
BIT32_ITEM( SQL_CONVERT_FUNCTIONS, GetInfoConvertFunctions ),
BIT32_ITEM( SQL_CORRELATION_NAME, GetInfoCorrelationName ),
BIT32_ITEM( SQL_CREATE_ASSERTION, GetInfoCreateAssertion ),
BIT32_ITEM( SQL_CREATE_CHARACTER_SET, GetInfoCreateCharset ),
BIT32_ITEM( SQL_CREATE_COLLATION, GetInfoCreateCollation ),
BIT32_ITEM( SQL_CREATE_DOMAIN, GetInfoCreateDomain ),
BIT32_ITEM( SQL_CREATE_SCHEMA, GetInfoCreateSchema ),
BIT32_ITEM( SQL_CREATE_TABLE, GetInfoCreateTable ),
BIT32_ITEM( SQL_CREATE_TRANSLATION, GetInfoCreateXlation ),
BIT32_ITEM( SQL_CREATE_VIEW, GetInfoCreateView ),
DEX32_ITEM( SQL_CURSOR_COMMIT_BEHAVIOR, GetInfoCommit ),
DEX32_ITEM( SQL_CURSOR_ROLLBACK_BEHAVIOR, GetInfoCommit ),
DEX32_ITEM( SQL_CURSOR_SENSITIVITY, GetInfoCursorSensitiv ),

STRNG_ITEM( SQL_DATA_SOURCE_NAME ),
STRNG_ITEM( SQL_DATA_SOURCE_READ_ONLY ),
STRNG_ITEM( SQL_DATABASE_NAME ),
BIT32_ITEM( SQL_DATETIME_LITERALS, GetInfoSQLDateLit ),
STRNG_ITEM( SQL_DBMS_NAME ),
STRNG_ITEM( SQL_DBMS_VER ),
BIT32_ITEM( SQL_DEFAULT_TXN_ISOLATION, GetInfoTXNIsolation ),
STRNG_ITEM( SQL_DESCRIBE_PARAMETER ),
INT32_ITEM( SQL_DRIVER_HDBC ),
INT32_ITEM( SQL_DRIVER_HENV ),
INT32_ITEM( SQL_DRIVER_HLIB ),
INT32_ITEM( SQL_DRIVER_HSTMT ),
STRNG_ITEM( SQL_DRIVER_NAME ),
STRNG_ITEM( SQL_DRIVER_ODBC_VER ),
STRNG_ITEM( SQL_DRIVER_VER ),
BIT32_ITEM( SQL_DROP_ASSERTION, GetInfoDropAssertion ),
BIT32_ITEM( SQL_DROP_CHARACTER_SET, GetInfoDropCharset ),
BIT32_ITEM( SQL_DROP_COLLATION, GetInfoDropCollation ),
BIT32_ITEM( SQL_DROP_DOMAIN, GetInfoDropDomain ),
BIT32_ITEM( SQL_DROP_SCHEMA, GetInfoDropSchema ),
BIT32_ITEM( SQL_DROP_TABLE, GetInfoDropTable ),
BIT32_ITEM( SQL_DROP_TRANSLATION, GetInfoDropXlation ),
BIT32_ITEM( SQL_DROP_VIEW, GetInfoDropView ),
BIT32_ITEM( SQL_DYNAMIC_CURSOR_ATTRIBUTES1, GetInfoCurAttrs1 ),
BIT32_ITEM( SQL_DYNAMIC_CURSOR_ATTRIBUTES2, GetInfoCurAttrs2 ),

STRNG_ITEM( SQL_EXPRESSIONS_IN_ORDERBY ),

DEX32_ITEM( SQL_FILE_USAGE, GetInfoFileUsage ),
BIT32_ITEM( SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1, GetInfoCurAttrs1 ),
BIT32_ITEM( SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2, GetInfoCurAttrs2 ),

BIT32_ITEM( SQL_GETDATA_EXTENSIONS, GetInfoGetdataExt ),
BIT32_ITEM( SQL_GROUP_BY, GetInfoGroupBy ),

DEX32_ITEM( SQL_IDENTIFIER_CASE, GetInfoIDCase ),
INT16_ITEM( SQL_IDENTIFIER_QUOTE_CHAR ),
BIT32_ITEM( SQL_INDEX_KEYWORDS, GetInfoIndexKeywords ),
BIT32_ITEM( SQL_INFO_SCHEMA_VIEWS, GetInfoInfoSchemaViews ),
STRNG_ITEM( SQL_INTEGRITY ),

BIT32_ITEM( SQL_KEYSET_CURSOR_ATTRIBUTES1, GetInfoCurAttrs1 ),
BIT32_ITEM( SQL_KEYSET_CURSOR_ATTRIBUTES2, GetInfoCurAttrs2 ),
STRNG_ITEM( SQL_KEYWORDS ),

STRNG_ITEM( SQL_LIKE_ESCAPE_CLAUSE ),

INT32_ITEM( SQL_MAX_ASYNC_CONCURRENT_STATEMENTS ),
INT32_ITEM( SQL_MAX_BINARY_LITERAL_LEN ),
INT16_ITEM( SQL_MAX_CATALOG_NAME_LEN ),
INT32_ITEM( SQL_MAX_CHAR_LITERAL_LEN ),
INT16_ITEM( SQL_MAX_COLUMN_NAME_LEN ),
INT16_ITEM( SQL_MAX_COLUMNS_IN_GROUP_BY ),
INT16_ITEM( SQL_MAX_COLUMNS_IN_INDEX ),
INT16_ITEM( SQL_MAX_COLUMNS_IN_ORDER_BY ),
INT16_ITEM( SQL_MAX_COLUMNS_IN_SELECT ),
INT16_ITEM( SQL_MAX_COLUMNS_IN_TABLE ),
INT16_ITEM( SQL_MAX_CONCURRENT_ACTIVITIES ),
INT16_ITEM( SQL_MAX_CURSOR_NAME_LEN ),
INT16_ITEM( SQL_MAX_DRIVER_CONNECTIONS ),
INT16_ITEM( SQL_MAX_IDENTIFIER_LEN ),
INT32_ITEM( SQL_MAX_INDEX_SIZE ),
INT16_ITEM( SQL_MAX_PROCEDURE_NAME_LEN ),
INT32_ITEM( SQL_MAX_ROW_SIZE ),
STRNG_ITEM( SQL_MAX_ROW_SIZE_INCLUDES_LONG ),
INT16_ITEM( SQL_MAX_SCHEMA_NAME_LEN ),
INT16_ITEM( SQL_MAX_STATEMENT_LEN ),
INT16_ITEM( SQL_MAX_TABLE_NAME_LEN ),
INT16_ITEM( SQL_MAX_TABLES_IN_SELECT ),
INT16_ITEM( SQL_MAX_USER_NAME_LEN ),
STRNG_ITEM( SQL_MULTIPLE_ACTIVE_TXN ),
STRNG_ITEM( SQL_MULT_RESULT_SETS ),

STRNG_ITEM( SQL_NEED_LONG_DATA_LEN ),
DEX32_ITEM( SQL_NON_NULLABLE_COLUMNS, GetInfoNonNullCols ),
DEX32_ITEM( SQL_NULL_COLLATION, GetInfoNullCollation ),
BIT32_ITEM( SQL_NUMERIC_FUNCTIONS, GetInfoNumeric ),

DEX32_ITEM( SQL_ODBC_INTERFACE_CONFORMANCE, GetInfoAPIConform ),
DEX32_ITEM( SQL_ODBC_SQL_CONFORMANCE, GetInfoODBCSQL ),
STRNG_ITEM( SQL_ODBC_VER ),
STRNG_ITEM( SQL_ORDER_BY_COLUMNS_IN_SELECT ),
STRNG_ITEM( SQL_OUTER_JOINS ),

DEX32_ITEM( SQL_PARAM_ARRAY_ROW_COUNTS, GetInfoParamRowCounts ),
DEX32_ITEM( SQL_PARAM_ARRAY_SELECTS, GetInfoParamSelects ),
STRNG_ITEM( SQL_PROCEDURES ),
STRNG_ITEM( SQL_PROCEDURE_TERM ),

DEX32_ITEM( SQL_QUOTED_IDENTIFIER_CASE, GetInfoIDCase ),

STRNG_ITEM( SQL_ROW_UPDATES ),

STRNG_ITEM( SQL_SCHEMA_TERM ),
BIT32_ITEM( SQL_SCHEMA_USAGE, GetInfoSchemaUsage ),
BIT32_ITEM( SQL_SCROLL_OPTIONS, GetInfoScrollOptions ),
STRNG_ITEM( SQL_SEARCH_PATTERN_ESCAPE ),
STRNG_ITEM( SQL_SERVER_NAME ),
STRNG_ITEM( SQL_SPECIAL_CHARACTERS ),
BIT32_ITEM( SQL_SQL_CONFORMANCE, GetInfoSQLConform ),
BIT32_ITEM( SQL_SQL92_DATETIME_FUNCTIONS, GetInfoS92DatetimeFns ),
BIT32_ITEM( SQL_SQL92_FOREIGN_KEY_DELETE_RULE, GetInfoS92FKeyDelRule ),
BIT32_ITEM( SQL_SQL92_FOREIGN_KEY_UPDATE_RULE, GetInfoS92FKeyUpdRule ),
BIT32_ITEM( SQL_SQL92_GRANT, GetInfoS92Grant ),
BIT32_ITEM( SQL_SQL92_NUMERIC_VALUE_FUNCTIONS, GetInfoS92NumValFns ),
BIT32_ITEM( SQL_SQL92_PREDICATES, GetInfoS92Predicates ),
BIT32_ITEM( SQL_SQL92_RELATIONAL_JOIN_OPERATORS, GetInfoS92RelJoinOps ),
BIT32_ITEM( SQL_SQL92_REVOKE, GetInfoS92Revoke ),
BIT32_ITEM( SQL_SQL92_ROW_VALUE_CONSTRUCTOR, GetInfoS92RowValConstr ),
BIT32_ITEM( SQL_SQL92_STRING_FUNCTIONS, GetInfoS92StringFns ),
BIT32_ITEM( SQL_SQL92_VALUE_EXPRESSIONS, GetInfoS92ValueExprs ),
BIT32_ITEM( SQL_STANDARD_CLI_CONFORMANCE, GetInfoS92StdCLIConf ),
BIT32_ITEM( SQL_STATIC_CURSOR_ATTRIBUTES1, GetInfoCurAttrs1 ),
BIT32_ITEM( SQL_STATIC_CURSOR_ATTRIBUTES2, GetInfoCurAttrs2 ),
BIT32_ITEM( SQL_STRING_FUNCTIONS, GetInfoStrings ),
BIT32_ITEM( SQL_SUBQUERIES, GetInfoSubqueries ),
BIT32_ITEM( SQL_SYSTEM_FUNCTIONS, GetInfoSystem ),

STRNG_ITEM( SQL_TABLE_TERM ),
BIT32_ITEM( SQL_TIMEDATE_ADD_INTERVALS, GetInfoTimeDateIvls ),
BIT32_ITEM( SQL_TIMEDATE_DIFF_INTERVALS, GetInfoTimeDateIvls ),
BIT32_ITEM( SQL_TIMEDATE_FUNCTIONS, GetInfoTimeDate ),
DEX32_ITEM( SQL_TXN_CAPABLE, GetInfoTxnCapable ),
BIT32_ITEM( SQL_TXN_ISOLATION_OPTION, GetInfoTxnIsoOptions ),

BIT32_ITEM( SQL_UNION, GetInfoUnion ),
STRNG_ITEM( SQL_USER_NAME ),


STRNG_ITEM( SQL_XOPEN_CLI_YEAR ),
};


//*---------------------------------------------------------------------------------
//| GetBitVal:
//| Call this function to retrieve the string values for all items which meet
//| the bitwise and condition.
//| Parms:
//| in rs Pointer to the results set
//| in szInfoName The info value being retrieved
//| in is Structure with resource ids and values
//| in maxdex Number of items in struct
//| in mask The value to compare against
//| in szOut Output buffer for retrieval
//| in cbOut Size of output buffer
//| Returns:
//| Nothing
//*---------------------------------------------------------------------------------
BOOL GetBitVal
(RESULTSSET FAR * rs,
LPSTR szInfoName,
lpINFOSTRUCT is,
int maxdex,
UDWORD mask,
LPSTR szVal,
int cbVal)
{
int tdex;
ROWDATA FAR * rd;
COLORREF rgbDft=GetDefaultRGB();

if (mask != 0) {
for(tdex=0; tdex<maxdex; tdex++)
if(is[tdex].fVal & mask) {
rd = AllocateRowData(rs, rgbDft, RDATA_DEFAULT_BKGRND);
SetColumnData(0, rd, szInfoName);
SetColumnData(1, rd, is[tdex].szStr);
if(AddRowData(rs, rd) == LB_ERRSPACE)
return FALSE;
}
}
else {
rd = AllocateRowData(rs, rgbDft, RDATA_DEFAULT_BKGRND);
SetColumnData(0, rd, szInfoName);
SetColumnData(1, rd, "0");
if(AddRowData(rs, rd) == LB_ERRSPACE)
return FALSE;
}

return TRUE;
}


//*---------------------------------------------------------------------------------
//| GetIndexVal:
//| Call this function to retrieve the string value for a constant.
//| Parms:
//| in rs Pointer to the results set
//| in szInfoName The info value being retrieved
//| in is Structure with resource ids and values
//| in maxdex Number of items in struct
//| in dex String index value
//| in szOut Output buffer for retrieval
//| in cbOut Size of output buffer
//| Returns:
//| FALSE if there is an error
//| No error is posted if matching value is not found.
//*---------------------------------------------------------------------------------
BOOL GetIndexVal
(RESULTSSET FAR * rs,
LPSTR szInfoName,
lpINFOSTRUCT is,
int maxdex,
int dex,
LPSTR szOut,
int cbOut)
{
int tdex;
ROWDATA FAR * rd;
COLORREF rgbDft=GetDefaultRGB();

for (tdex = 0; tdex<maxdex; tdex++)
if (is[tdex].fVal == (UDWORD) dex) {
rd = AllocateRowData(rs, rgbDft, RDATA_DEFAULT_BKGRND);
SetColumnData(0, rd, szInfoName);
SetColumnData(1, rd, is[tdex].szStr);
if(AddRowData(rs, rd) == LB_ERRSPACE)
return FALSE;
}

return TRUE;
}


//*---------------------------------------------------------------------------------
//| DisplayGetInfo:
//| This function goes through all of the SQLGetInfo constants defined in the
//| ODBC reference guide and displays them in a results set.
//| Parms:
//| in ci CHILDINFO information
//| Returns:
//| TRUE if successful,
//| FALSE on error
//*---------------------------------------------------------------------------------
BOOL DisplayGetInfo(CHILDINFO FAR * ci)
{
char szTitle[MAXBUFF];
char szVal[MAXBUFF];
int dex;
lpINFOSTRUCT lpINFS;
RESULTSSET FAR * rs;
ROWDATA FAR * rd;
RETCODE retcode;
COLORREF rgbDft=GetDefaultRGB();

//
// Create a hard coded results set with 2 columns
//
lstrcpy((LPSTR)szTitle, (LPSTR)ci->szClientTitle);
lstrcat((LPSTR)szTitle, (LPSTR)szDash);
lstrcat((LPSTR)szTitle, (LPSTR)szGetInfoTitle);
rs = GetConnectWindowResultsNode(ci);
if(!CreateResultsSet(rs, ci->hwndClient, ci->hInst, 2, (LPSTR)szTitle))
return FALSE;

//
// Set the meta data
//
SetMetaDataColumn(rs, 0, (LPSTR)"fInfoType",
GetTypeName(SQL_TYPE, SQL_CHAR), SQL_CHAR, 40, 0,
45, TA_LEFT);
SetMetaDataColumn(rs, 1, (LPSTR)"Value",
GetTypeName(SQL_TYPE, SQL_CHAR), SQL_CHAR, 70, 0,
70, TA_LEFT);

//
// Now create the MDI child window which will hold the results.
//
if(!CreateResultsWindow(ci, rs))
goto exit00;


//
// Loop through the control structure and check each fInfoType. Certain
// types require extra processing.
//
Busy(TRUE);
for(dex=0; dex<NumItems(GetInfo); dex++) {
if(GetInfo[dex].fInfoType == SQL_DRIVER_HSTMT) // Input arg also
*(HSTMT FAR *)GetInfo[dex].rgbInfoValue = ci->hstmt;

memset(GetInfo[dex].rgbInfoValue, 0, GetInfo[dex].cbInfoMax);

retcode = SQLGetInfo(ci->hdbc,
GetInfo[dex].fInfoType,
GetInfo[dex].rgbInfoValue,
GetInfo[dex].cbInfoMax,
NULL);
if(retcode != SQL_SUCCESS)
PrintErrors(ci, SQL_HANDLE_DBC);

switch(GetInfo[dex].fInfoType) {
case SQL_DRIVER_HENV:
case SQL_DRIVER_HDBC:
case SQL_DRIVER_HSTMT:
rd = AllocateRowData(rs, rgbDft, RDATA_DEFAULT_BKGRND);
SetColumnData(0, rd, GetInfo[dex].szInfoName);
wsprintf(szVal, "%04X:%04X", HIWORD(cb32), LOWORD(cb32));
SetColumnData(1, rd, (LPSTR)szVal);
if(AddRowData(rs, rd) == LB_ERRSPACE)
goto exit00;
break;

//
// The default action is taken when we only need to display the
// value as is. We can use the structure to figure out what
// format it is in.
//
default:
rd = AllocateRowData(rs, rgbDft, RDATA_DEFAULT_BKGRND);
SetColumnData(0, rd, GetInfo[dex].szInfoName);
switch(GetInfo[dex].fOutType) {
case INT16:
wsprintf(szVal, "%d", cb16);
SetColumnData(1, rd, (LPSTR)szVal);
if(AddRowData(rs, rd) == LB_ERRSPACE)
goto exit00;
break;

case INT32:
wsprintf(szVal, "%ld", cb32);
SetColumnData(1, rd, (LPSTR)szVal);
if(AddRowData(rs, rd) == LB_ERRSPACE)
goto exit00;
break;

case DEXVAL:
lpINFS = (lpINFOSTRUCT)GetInfo[dex].ptr;
if(!GetIndexVal(rs, GetInfo[dex].szInfoName,
lpINFS, GetInfo[dex].cbNum,
cb32,
(LPSTR)szVal, sizeof(szVal)))
goto exit00;
break;

case BITVAL:
lpINFS = (lpINFOSTRUCT)GetInfo[dex].ptr;
if(!GetBitVal(rs, GetInfo[dex].szInfoName,
lpINFS, GetInfo[dex].cbNum,
cb32,
(LPSTR)szVal, sizeof(szVal)))
goto exit00;
break;

default:
szGetInfo[69] = '\0'; // truncate long string...
SetColumnData(1, rd, (LPSTR)GetInfo[dex].rgbInfoValue);
if(AddRowData(rs, rd) == LB_ERRSPACE)
goto exit00;
break;
}
}

}

Busy(FALSE);
return TRUE;

exit00:
Busy(FALSE);
return FALSE;
}


//*---------------------------------------------------------------------------------
//| DisplayODBCFunctions:
//| This function will enumerate all of the ODBC functions in a results set
//| and indicate which ones are supported. The results set is attatched
//| as a valid results window on the current child.
//| Parms:
//| in ci CHILDINFO information
//| Returns:
//| TRUE if successful,
//| FALSE on error
//*---------------------------------------------------------------------------------
BOOL DisplayODBCFunctions(CHILDINFO FAR * ci)
{
UWORD fSupport;
char szFuncName[35];
char szTitle[MAXBUFF];
int dex;
RESULTSSET FAR * rs;
ROWDATA FAR * rd;
RETCODE retcode;
COLORREF rgbDft=GetDefaultRGB();
//
// Create a hard coded results set with 3 columns
//
lstrcpy((LPSTR)szTitle, (LPSTR)ci->szClientTitle);
lstrcat((LPSTR)szTitle, (LPSTR)szDash);
lstrcat((LPSTR)szTitle, (LPSTR)szODBCFunctions);
rs = GetConnectWindowResultsNode(ci);
if(!CreateResultsSet(rs, ci->hwndClient, ci->hInst, 3, (LPSTR)szTitle))
return FALSE;

//
// Set the meta data
//
SetMetaDataColumn(rs, 0, (LPSTR)"Function",
GetTypeName(SQL_TYPE, SQL_CHAR), SQL_CHAR, 20, 0,
25, TA_LEFT);
SetMetaDataColumn(rs, 1, (LPSTR)"Conformance",
GetTypeName(SQL_TYPE, SQL_CHAR), SQL_CHAR, 10, 0,
10, TA_LEFT);
SetMetaDataColumn(rs, 2, (LPSTR)"Supported",
GetTypeName(SQL_TYPE, SQL_CHAR), SQL_CHAR, 10, 0,
10, TA_LEFT);

//
// Now create the MDI child window which will hold the results.
//
if(!CreateResultsWindow(ci, rs))
goto exit00;


//
// Loop through the control structure and check each function. For each row
// add a record with the function name, conformance level, and Yes if
// supported, No if not.
//
for(dex=0; dex<NumItems(ODBCFunctions); dex++) {
retcode = SQLGetFunctions(ci->hdbc,
ODBCFunctions[dex].fFunction, &fSupport);
if(retcode != SQL_SUCCESS)
PrintErrors(ci, SQL_HANDLE_DBC);
iLoadString(ODBCFunctions[dex].idFunction, (LPSTR)szFuncName, sizeof(szFuncName));
rd = AllocateRowData(rs, rgbDft, RDATA_DEFAULT_BKGRND);
SetColumnData(0, rd, szFuncName);
SetColumnData(1, rd, ODBCFunctions[dex].szLevel);
SetColumnData(2, rd, (fSupport) ? (LPSTR)szYes : (LPSTR)szNo);
AddRowData(rs, rd);
}

return TRUE;

exit00:
SQLFreeStmt(ci->hstmt, SQL_CLOSE);
return FALSE;
}


//*---------------------------------------------------------------------------------
//| DisplayODBCDataSources:
//| This function will enumerate all of the ODBC Data sources.
//| Parms:
//| in ci CHILDINFO information
//| Returns:
//| TRUE if successful,
//| FALSE on error
//*---------------------------------------------------------------------------------
BOOL DisplayODBCDataSources(CHILDINFO FAR * ci)
{
HENV henv;
RESULTSSET FAR * rs;
ROWDATA FAR * rd;
RETCODE retcode;
char szDSN[SQL_MAX_DSN_LENGTH + 1];
char szDesc[MAXBUFF];
char szTitle[MAXBUFF];
COLORREF rgbDft=GetDefaultRGB();

//
// Create a hard coded results set with 2 columns
//
lstrcpy((LPSTR)szTitle, (LPSTR)ci->szClientTitle);
lstrcat((LPSTR)szTitle, (LPSTR)szDash);
lstrcat((LPSTR)szTitle, (LPSTR)szODBCDataSources);
rs = GetConnectWindowResultsNode(ci);
if(!CreateResultsSet(rs, ci->hwndClient, ci->hInst, 2, (LPSTR)szTitle))
return FALSE;

//
// Set the meta data
//
SetMetaDataColumn(rs, 0, (LPSTR)"Driver",
GetTypeName(SQL_TYPE, SQL_CHAR), SQL_CHAR, 15, 0,
15, TA_LEFT);
SetMetaDataColumn(rs, 1, (LPSTR)"Description",
GetTypeName(SQL_TYPE, SQL_CHAR), SQL_CHAR, 35, 0,
35, TA_LEFT);

//
// Now create the MDI child window which will hold the results.
//
if(!CreateResultsWindow(ci, rs))
goto exit00;


//
// Loop through each data source and add it to the results set.
//
if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HENV, &henv) )
{
PrintErrors(ci, SQL_HANDLE_ENV);
goto exit00;
}
if (SQL_SUCCESS != SQLSetEnvAttr(henv,SQL_ATTR_ODBC_VERSION,
(SQLPOINTER)SQL_OV_ODBC3,SQL_IS_INTEGER))
{
PrintErrors(ci, SQL_HANDLE_ENV);
goto exit00;
}

retcode = SQLDataSources(henv, SQL_FETCH_FIRST, szDSN, sizeof(szDSN),
NULL, szDesc, sizeof(szDesc), NULL);
while(retcode != SQL_NO_DATA) {
if(retcode != SQL_SUCCESS )
{
PrintErrors(ci, SQL_HANDLE_ENV);
if (retcode != SQL_SUCCESS_WITH_INFO)
goto exit00;
}
rd = AllocateRowData(rs, rgbDft, RDATA_DEFAULT_BKGRND);
SetColumnData(0, rd, szDSN);
SetColumnData(1, rd, szDesc);
AddRowData(rs, rd);
retcode = SQLDataSources(henv, SQL_FETCH_NEXT, szDSN, sizeof(szDSN),
NULL, szDesc, sizeof(szDesc), NULL);
}
SQLFreeHandle(SQL_HANDLE_ENV, henv);

return TRUE;

exit00:

return FALSE;
}



//*---------------------------------------------------------------------------------
//| DisplayODBCDataTypes:
//| This function will enumerate data type information.
//| Parms:
//| in ci CHILDINFO information
//| Returns:
//| TRUE if successful,
//| FALSE on error
//*---------------------------------------------------------------------------------
BOOL DisplayODBCDataTypes(CHILDINFO FAR * ci)
{
RESULTSSET FAR * rs;
RETCODE retcode;
SWORD cbCols;
char szTitle[MAXBUFF];

//
// We'll use SQLGetTypeInfo for this query. Since this function can return more
// than the standard types, we must first execute the query and then create
// the results set.
//
lstrcpy((LPSTR)szTitle, (LPSTR)ci->szClientTitle);
lstrcat((LPSTR)szTitle, (LPSTR)szDash);
lstrcat((LPSTR)szTitle, (LPSTR)szODBCDataTypes);
retcode = SQLGetTypeInfo(ci->hstmt, SQL_ALL_TYPES);
if(retcode != SQL_SUCCESS) {
PrintErrors(ci, SQL_HANDLE_STMT);
return FALSE;
}

if(!(cbCols = GetNumResultsCols(ci->hstmt)))
return FALSE;

rs = GetConnectWindowResultsNode(ci);
if(!CreateResultsSet(rs, ci->hwndClient, ci->hInst, cbCols, (LPSTR)szTitle))
return FALSE;

//
// Set the meta data
//
SetMetaDataFromSql(ci->hwndOut, ci->hstmt, rs, cbCols);

//
// Now create the MDI child window which will hold the results.
//
if(!CreateResultsWindow(ci, rs))
goto exit00;


//
// Loop through each data source and add it to the results set.
//
FetchAllRecordsToResults(ci->hwndOut, ci->hstmt, rs, cbCols, TRUE);
SQLFreeStmt(ci->hstmt, SQL_CLOSE);

return TRUE;

exit00:
return FALSE;
}



//*---------------------------------------------------------------------------------
//| EditPipe:
//| This function allows the user to create a new pipe.
//| Parms:
//| in ci CHILDINFO information
//| Returns:
//| TRUE if successful,
//| FALSE on error
//*---------------------------------------------------------------------------------
void EditPipe(CHILDINFO FAR * ci)
{
HWND fHwnd=GetFocus();

if(-1 == DialogBoxParam(ci->hInst,
MAKEINTRESOURCE(IDD_EDIT_PIPE),
ci->hwnd,
(DLGPROC) EditPipeWndProc, (LPARAM)ci))
MessageBox(NULL, "Could not open dialog box.",
"Pipe", MB_ICONEXCLAMATION);

if(fHwnd)
SetFocus(fHwnd);
}



//*------------------------------------------------------------------------
//| IsValidParms:
//| Verify that the parameters specified are the correct comma
//| separated format.
//| Parms:
//| hwnd Window handle for errors
//| szParms The null terminated list of parms
//| Returns:
//| TRUE if they are valid, FALSE on error
//*------------------------------------------------------------------------
BOOL WINAPI IsValidParms(HWND hwnd, LPSTR szParms)
{
LPSTR str=szParms, nstr;
char sztmp[MAXSQL];
int iNum, iCnt=0;

lstrcpy(sztmp, szParms);
nstr = str = strtok(sztmp, szCOMMA);
while(str) {
++iCnt;
if(!(strlen(str) == 1 && *str == '0')) {
iNum = atoi(str);
while(*str) {
if(*str < '0' ||
*str > '9')
goto invalidint;
++str;
}

// It was not 0, so if atoi returned 0 it was invalid
if(!iNum)
goto invalidint;
}

nstr = str = strtok(NULL, szCOMMA);
}

if(iCnt <= MAXPARMS)
return TRUE;
else {
szMessageBox(hwnd,
MB_ICONEXCLAMATION | MB_OK,
(LPSTR)szErrorMsgTitle,
iLoadString(idsTooManyParms, OutStr, MAXBUFF),
iCnt,
MAXPARMS);
return FALSE;
}

invalidint:
szMessageBox(hwnd,
MB_ICONEXCLAMATION | MB_OK,
(LPSTR)szErrorMsgTitle,
iLoadString(idsInvalidInt, OutStr, MAXBUFF),
nstr);

return FALSE;
}


//*------------------------------------------------------------------------
//| EditPipeWndProc:
//| Message handler for creating a new pipe.
//| Parms:
//| in Standard window parms
//| Returns:
//| Depends on message
//*------------------------------------------------------------------------
BOOL EXTFUN EditPipeWndProc(HWND hDlg, unsigned msg, WPARAM wParam, LPARAM lParam)
{
static CHILDINFO FAR * ci;
static cbNames;
static char szName[MAXNAME];

switch(msg) {
case WM_INITDIALOG:
{
ci = (CHILDINFO FAR *)lParam;
CenterDialog(hDlg);

SendMessage(GetDlgItem(hDlg, IDC_NAME), CB_LIMITTEXT, MAXPARMS, 0L);
SendMessage(GetDlgItem(hDlg, IDE_SQL), EM_LIMITTEXT, MAXSQL, 0L);
SendMessage(GetDlgItem(hDlg, IDE_PARMS), EM_LIMITTEXT, (MAXNAME*2), 0L);
CheckRadioButton(hDlg, IDR_VALUE, IDR_ADDRESS, IDR_VALUE);
SendMessage(hDlg, USER_RESETLIST, 0, 0L);
SendMessage(hDlg, USER_SETSTATES, 0, 0L);
}
return TRUE;


// This user message is sent when the list needs to be refreshed
case USER_RESETLIST:
{
LPSTR str, addstr;

addstr = str = (LPSTR)GetMemory(1000);
if(!addstr)
return TRUE;
cbNames = 0;
if(str) {
SendMessage(GetDlgItem(hDlg, IDC_NAME), CB_RESETCONTENT, 0, 0L);
if(GetPrivateProfileString((LPSTR)szPIPES, NULL, NULL,
str, 1000, szLABINI))
while(*addstr) {
++cbNames;
SendMessage(GetDlgItem(hDlg, IDC_NAME),
CB_ADDSTRING, 0,
(LPARAM)(LPSTR)addstr);
addstr = addstr + lstrlen(addstr) + 1;
}
}
ReleaseMemory(str);
if(cbNames)
SendMessage(GetDlgItem(hDlg, IDC_NAME), CB_SETCURSEL, 0, 0L);
SendMessage(hDlg, USER_SETDEFAULTS, 0, 0L);
SendMessage(hDlg, USER_SETSTATES, 0, 0L);
}
return TRUE;

// This user defined message will set the state of controls
case USER_SETSTATES:
EnableWindow(GetDlgItem(hDlg, IDB_DELETE), cbNames);
EnableWindow(GetDlgItem(hDlg, IDE_SQL), cbNames);
EnableWindow(GetDlgItem(hDlg, IDR_VALUE), cbNames);
EnableWindow(GetDlgItem(hDlg, IDR_ADDRESS), cbNames);
EnableWindow(GetDlgItem(hDlg, IDE_PARMS), cbNames);
EnableWindow(GetDlgItem(hDlg, IDOK), cbNames);
return TRUE;

// This user defined message is for setting default values
case USER_SETDEFAULTS:
{
char szParmType[10];
char szSql[MAXSQL];
char szParms[MAXBUFF];

HWND hName = GetDlgItem(hDlg, IDC_NAME);

if(cbNames == 0) { // No current driver
SetDlgItemText(hDlg, IDE_SQL, "");
SetDlgItemText(hDlg, IDE_PARMS, "");
return TRUE;
}
SendMessage(hName, CB_GETLBTEXT,
(WPARAM)SendMessage(hName, CB_GETCURSEL, 0, 0L),
(LPARAM)(LPSTR)szName);
if(GetPrivateProfileString(szName, szSQL, NULL, szSql, sizeof(szSql), szLABINI))
SetDlgItemText(hDlg, IDE_SQL, szSql);
else
SetDlgItemText(hDlg, IDE_SQL, "");
if(GetPrivateProfileString(szName, szPARMS, NULL, szParms, sizeof(szParms), szLABINI))
SetDlgItemText(hDlg, IDE_PARMS, szParms);
else
SetDlgItemText(hDlg, IDE_PARMS, "");
if(GetPrivateProfileString(szName, szPARMOPT, NULL, szParmType, sizeof(szParmType), szLABINI))
if(lstrcmpi(szVALUE, szParmType) == 0)
CheckRadioButton(hDlg, IDR_VALUE, IDR_ADDRESS, IDR_VALUE);
else
CheckRadioButton(hDlg, IDR_VALUE, IDR_ADDRESS, IDR_ADDRESS);
CheckDlgButton(hDlg, IDX_DELETE, GetPrivateProfileInt(szName, szDELETEOPT, 0, szLABINI));
}
return TRUE;

case WM_COMMAND:
switch(GET_WM_COMMAND_ID(wParam, lParam)) {
case IDB_NEW:
{
NEWPIPE np;

np.hwnd = hDlg;
np.hInst = ci->hInst;
NewPipe(&np);
if(np.fSuccess) {
lstrcpy(szName, np.szName);
SendMessage(GetDlgItem(hDlg, IDC_NAME), CB_SETCURSEL,
(WPARAM)SendMessage(GetDlgItem(hDlg, IDC_NAME), CB_ADDSTRING,
0, (LPARAM)(LPSTR)szName), 0L);
if(cbNames)
SendMessage(hDlg, USER_SETDEFAULTS, 0, 0L);
else
SendMessage(hDlg, USER_RESETLIST, 0, 0L);
}
}
return TRUE;

case IDB_DELETE:
GetText(GetDlgItem(hDlg, IDC_NAME), szName);
wsprintf(OutStr, szDeletePipe, (LPSTR)szName);
if(IDOK == MessageBox(hDlg, OutStr, szEditPipe, MB_OKCANCEL)) {
WritePrivateProfileString(szName, NULL, NULL, szLABINI);
WritePrivateProfileString(szPIPES, szName, NULL, szLABINI);
SendMessage(hDlg, USER_RESETLIST, 0, 0L);
}
return TRUE;

//
// Read in the info from the dialog, validate the parms, write to file
//
case IDOK:
{
char szSql[MAXSQL];
char szParms[MAXBUFF];

GetDlgItemText(hDlg, IDC_NAME, (LPSTR)szName, sizeof(szName));

GetDlgItemText(hDlg, IDE_PARMS, szParms, sizeof(szParms));
if(IsValidParms(hDlg, szParms)) {
WritePrivateProfileString(szName, szPARMS, szParms, szLABINI);

GetDlgItemText(hDlg, IDE_SQL, szSql, sizeof(szSql));
WritePrivateProfileString(szName, szSQL, szSql, szLABINI);

if(IsDlgButtonChecked(hDlg, IDR_VALUE))
WritePrivateProfileString(szName, szPARMOPT, szVALUE, szLABINI);
else
WritePrivateProfileString(szName, szPARMOPT, szADDRESS, szLABINI);

WritePrivateProfileString(szName, szDELETEOPT,
(IsDlgButtonChecked(hDlg, IDX_DELETE)) ? (LPSTR)"1" : (LPSTR)"0",
szLABINI);
}
}
return TRUE;

case IDCANCEL:
EndDialog(hDlg, IDCANCEL);;
return TRUE;
}
// Now check for control notification messages
switch(HIWORD(lParam)) {
case CBN_SELENDOK:
case CBN_KILLFOCUS:
SendMessage(hDlg, USER_SETDEFAULTS, TRUE, 0L);
return TRUE;

default:
break;
}
break;


default:
return FALSE;
}
return FALSE;
}


//*---------------------------------------------------------------------------------
//| NewPipe:
//| This function allows the user to create a new pipe.
//| Parms:
//| in ci CHILDINFO information
//| Returns:
//| Nothing
//*---------------------------------------------------------------------------------
void NewPipe(NEWPIPE FAR * np)
{
HWND fHwnd=GetFocus();

if(-1 == DialogBoxParam(np->hInst,
MAKEINTRESOURCE(IDD_NEW_PIPE),
np->hwnd,
(DLGPROC) NewPipeWndProc, (LPARAM)np))
MessageBox(NULL, "Could not open dialog box.",
"Pipe", MB_ICONEXCLAMATION);

if(fHwnd)
SetFocus(fHwnd);
}


//*------------------------------------------------------------------------
//| NewPipeWndProc:
//| Message handler for creating a new pipe.
//| Parms:
//| in Standard window parms
//| Returns:
//| Depends on message
//*------------------------------------------------------------------------
BOOL EXTFUN NewPipeWndProc(HWND hDlg, unsigned msg, WPARAM wParam, LPARAM lParam)
{
char szName[MAXNAME];
static NEWPIPE FAR * np;

switch(msg) {
case WM_INITDIALOG:
{
np = (NEWPIPE FAR *)lParam;
CenterDialog(hDlg);
SendMessage(GetDlgItem(hDlg, IDE_NAME), EM_LIMITTEXT, MAXNAME, 0L);
}
return TRUE;


case WM_COMMAND:
switch(GET_WM_COMMAND_ID(wParam, lParam)) {
case IDOK:
{
char szTmp[MAXNAME];

//
// Don't allow names with [,], or = in them, nor any
// reserved section names
//
GetText(GetDlgItem(hDlg, IDE_NAME), (LPSTR)szName);
if(!ValidName((LPSTR)szName) ||
!*szName ||
!lstrcmpi((LPSTR)szName, szSCREEN) ||
!lstrcmpi((LPSTR)szName, szFONT) ||
!lstrcmpi((LPSTR)szName, szCONNECTOPTIONS) ||
!lstrcmpi((LPSTR)szName, szPIPES)) {

szMessageBox(hDlg,
MB_ICONEXCLAMATION | MB_OK,
(LPSTR)szErrorMsgTitle,
iLoadString(idsInvalidName, OutStr, MAXBUFF),
(LPSTR)szName);
return TRUE;
}
if(GetPrivateProfileString(szPIPES, szName, NULL,
szTmp, sizeof(szTmp), szLABINI))
MessageBox(hDlg, szDuplicatePipe, szEditPipe, MB_OK);
else {
lstrcpy(np->szName, szName);
np->fSuccess = TRUE;
WritePrivateProfileString(szPIPES, szName, szInstalled, szLABINI);
EndDialog(hDlg, IDOK);
}
}
return TRUE;

case IDCANCEL:
np->fSuccess = FALSE;
EndDialog(hDlg, IDCANCEL);
return TRUE;
}
break;

default:
return FALSE;
}
return FALSE;
}



//*---------------------------------------------------------------------------------
//| HandlePipe:
//| This function will use the active results set and run use pipes against it.
//| Parms:
//| lpci Connection window information
//| lpri Ative results set
//| Returns:
//| Nothing.
//*---------------------------------------------------------------------------------
void INTFUN HandlePipe(lpCHILDINFO lpci, lpRESULTSINFO lpri)
{
HWND fHwnd=GetFocus();

if(-1 == DialogBoxParam(lpci->hInst,
MAKEINTRESOURCE(IDD_DO_PIPE),
lpci->hwnd,
(DLGPROC) DoPipeWndProc, (LPARAM)(lpRESULTSINFO)lpri))
MessageBox(NULL, "Could not open dialog box.",
"HandlePipe", MB_ICONEXCLAMATION);

if(fHwnd)
SetFocus(fHwnd);
}


//*------------------------------------------------------------------------
//| DoPipeWndProc:

//|   Handle dialog messages for IDD_DO_PIPE. 
//| Parms:
//| in Standard window parms
//| Returns:
//| Depends on message
//*------------------------------------------------------------------------
BOOL EXTFUN DoPipeWndProc(HWND hDlg, unsigned msg, WPARAM wParam, LPARAM lParam)
{
static CHILDINFO FAR * ci;
static RESULTSSET FAR * rs;
static SDWORD cbPipes;

switch(msg) {
case WM_INITDIALOG:
{
lpRESULTSINFO rwi;
rwi = (lpRESULTSINFO)lParam;
ci = rwi->ci;
rs = rwi->rs;
CenterDialog(hDlg);
cbPipes = RefreshPipeList(GetDlgItem(hDlg, IDL_PIPES));
EnableWindow(GetDlgItem(hDlg, IDL_PIPES), (int)(cbPipes));
EnableWindow(GetDlgItem(hDlg, IDOK), (int)(cbPipes));
}
return TRUE;


case WM_COMMAND:
switch(GET_WM_COMMAND_ID(wParam, lParam)) {
// User has clicked OK. Retrieve an array of the selected indexes
// and run the current pipe against each. Finally see if this
// pipe wants to delete items.
case IDOK:
{
int cbCnt;
int FAR * xSel;
int dex;
char szPipeName[MAXBUFF];

Busy(TRUE);
cbCnt = (int)SendMessage(rs->hwndList, LB_GETSELCOUNT, 0, 0L);
xSel = (int FAR *)GetMemory(sizeof(int) * cbCnt);
if(!xSel) {
Busy(FALSE);
return TRUE;
}
SendMessage(rs->hwndList, LB_GETSELITEMS, cbCnt, (LPARAM)(int FAR *)xSel);
SendMessage(GetDlgItem(hDlg, IDL_PIPES), LB_GETTEXT,
(WPARAM)SendMessage(GetDlgItem(hDlg, IDL_PIPES), LB_GETCURSEL, 0, 0L),
(LPARAM)(LPSTR)szPipeName);
DoPipe(rs, ci, (LPSTR)szPipeName, xSel, cbCnt);
if(GetPrivateProfileInt(szPipeName, szDELETEOPT, 0, szLABINI))
for(dex=cbCnt-1; dex>=0; dex--)
SendMessage(rs->hwndList, LB_DELETESTRING, xSel[dex], 0L);
Busy(FALSE);
ReleaseMemory(xSel);
}
return TRUE;

case IDCANCEL:
EndDialog(hDlg, IDCANCEL);
return TRUE;
}
return TRUE;

default:
return FALSE;
}
return FALSE;
}




//*---------------------------------------------------------------------------------
//| RefreshPipeList:
//| This function will reset the list of pipes based on the values returned
//| from GetPipeName. Having this extra level of abstraction allows us
//| to change the location of the pipes without affecting this code.
//| Parms:
//| in hwnd Window handle to list box to fill
//| Returns:
//| Number of items selected
//*---------------------------------------------------------------------------------
SDWORD RefreshPipeList(HWND hDlg)
{
#define MAX_PIPE_SIZE 4000
LPSTR szPipes, str;
SDWORD count=0;

szPipes = (LPSTR)GetMemory(MAX_PIPE_SIZE);
if(!szPipes)
return 0;

SendMessage(hDlg, LB_RESETCONTENT, 0, 0L);
GetPipeNames((LPSTR)szPipes, MAX_PIPE_SIZE);
str = szPipes;
while(*str) {
SendMessage(hDlg, LB_ADDSTRING, 0, (LPARAM)(LPSTR)str);
str += lstrlen(str) + 1;
++count;
}
if(count)
SendMessage(hDlg, LB_SETCURSEL, 0, 0L);

ReleaseMemory(szPipes);
return count;
}


//*---------------------------------------------------------------------------------
//| DoPipe:
//| This function will implement a pipe against the object which is passed in.
//| Parms:
//| in rs Pointer to results set describing data
//| in ci Connection window information
//| in szPipeName Name of pipe to use
//| in xPipes Array of items to pipe
//| in cbCnt Number of items
//| Returns:
//| Nothing.
//*---------------------------------------------------------------------------------
void DoPipe(RESULTSSET FAR * rs, CHILDINFO FAR * ci, LPSTR szPipeName,
int FAR xPipes[], int cbCnt)
{
SDWORD cbDataAtExec=SQL_DATA_AT_EXEC;
int dex;
int cParm;
char szpsql[200];
char szparms[35];
char parmopt[10];
UWORD cParmCnt=0;
LPSTR str=szparms;
LPSTR numstr=szparms;
ROWDATA FAR * rd;
RETCODE retcode;

//
// Make sure we can retrieve the pipe from the .ini file. Also get the parameter
// values if they are available.
//
if(!GetPrivateProfileString(szPipeName, szSQL, NULL, szpsql, sizeof(szpsql), szLABINI)) {
szWrite(ci->hwndOut,
GetidsString(idsPipeNotFound, OutStr, MAXBUFF),
(LPSTR)szPipeName);
return;
}
GetPrivateProfileString(szPipeName, szPARMS, NULL, szparms, sizeof(szparms), szLABINI);
GetPrivateProfileString(szPipeName, szPARMOPT, NULL, parmopt, sizeof(parmopt), szLABINI);

//
// If there are parameters to set, set each one based on user desription
//
if(str && *str)
PrepareParmList(str);
SQLFreeStmt(ci->hstmt, SQL_CLOSE);

//
// What type of parameter passing to do? value means substitue text and execute,
// address means use parameter data. The following will handle the former, the
// next more complicated routine will pass parameters.
//
if(lstrcmpi(parmopt, szVALUE) == 0) {
DoPipeByValue(rs, ci, szpsql, str, xPipes, cbCnt, (LPSTR)szPipeName);
return;
}

//
// Now prepare the user's statement, return on error
//
retcode = SQLPrepare(ci->hstmt, szpsql, SQL_NTS);
if(retcode != SQL_SUCCESS) {
PrintErrors(ci, SQL_HANDLE_STMT);
return;
}

//
// For each parameter, make sure it's in our range, then see which mode we want,
// address (param data) or value (textual substitution).
//
while(*str) {
++cParmCnt;
cParm = lpatoi(str);
if(cParm > rs->cbColumns)
szWrite(ci->hwndOut,
GetidsString(idsInvalidParamValue, OutStr, MAXBUFF),
cParm, (LPSTR)szPipeName);
else {
retcode = SQLBindParameter(ci->hstmt,
cParmCnt, SQL_PARAM_INPUT,
SQL_C_CHAR, SQL_CHAR,
rs->md[cParm-1].precision,
rs->md[cParm-1].scale,
(PTR FAR *)(cParm - 1),
rs->md[cParm-1].precision,
&cbDataAtExec);
if(retcode != SQL_SUCCESS)
PrintErrors(ci, SQL_HANDLE_STMT);
}
str += lstrlen(str) + 1;
}


//
// For each row selected, retrieve the row data structure associated with it,
// then do an execute. When prompted for SQL_NEED_DATA, substitute the
// correct parameter address.
//
for(dex=0; dex<cbCnt; dex++) {
int cNeedParm;
rd = (ROWDATA FAR *)SendMessage(rs->hwndList, LB_GETITEMDATA, (WPARAM)xPipes[dex], 0L);
retcode = SQLExecute(ci->hstmt);
switch(retcode) {
//
// User had parameter data which we are being prompted for. Since we
// did the SQLSetParam using the index number, we simply use that
// value to index into our column data and give the driver what
// it requires.
//
case SQL_NEED_DATA:
retcode = SQLParamData(ci->hstmt, (PTR FAR *)&cNeedParm);
while(retcode == SQL_NEED_DATA) {
retcode = SQLPutData(ci->hstmt, rd->cd[cNeedParm].szCols, SQL_NTS);
retcode = SQLParamData(ci->hstmt, (PTR FAR *)&cNeedParm);
}
break;

case SQL_SUCCESS:
CheckForResults(ci);
break;

default:
PrintErrors(ci, SQL_HANDLE_STMT);
break;
}
}

SQLFreeStmt(ci->hstmt, SQL_CLOSE);
return;
}



//*---------------------------------------------------------------------------------
//| PrepareParmList:
//| The user will enter a list of numbers separated by columns which will
//| designate which parms go for what marker. We will turn this list into
//| a double-null terminated list which can be used later for retrieval.
//| Parms:
//| in str Pointer to string to work on
//| Returns:
//| Nothing.
//*---------------------------------------------------------------------------------
void PrepareParmList(LPSTR str)
{
LPSTR tmpstr=str;
LPSTR lststr=tmpstr;

//
// Convert parm list into a double-null terminated list
//
while(tmpstr) {
if((tmpstr = _fstrchr(str, ','))) {
lststr = tmpstr + 1;
*tmpstr++ = '\0';
}
else {
lststr += lstrlen(lststr) + 1;
*lststr = '\0';
}
}
}



//*---------------------------------------------------------------------------------
//| DoPipeByValue:
//| This function will process all of the selcted values by creating a
//| statement which has all parameters embedded in it.
//|
//| Note: There are some servers which use a semi-colon for the name of
//| a stored procedure, but which cannot handle doing a drop of the
//| object with this name. If the pipe name is the reserved name
//| of "Drop Procedure (with semi-colon)" then we will strip off the
//| name since this can't really be done any other way.
//| Parms:
//| in rs Results set pointer
//| in ci Child information
//| in szUserSQL Statement with parameter markers
//| in szParms Parameter list, double null terminated
//| in xPipes Array of indexes to use for param data
//| in cbCnt Number of records to process
//| in szPipeName Pipe names
//| Returns:
//| Nothing.
//*---------------------------------------------------------------------------------
void DoPipeByValue(RESULTSSET FAR * rs, CHILDINFO FAR * ci, LPSTR szUserSQL,
LPSTR szParms, int FAR xPipes[], int cbCnt, LPSTR szPipeName)
{
char szUserSQLCopy[300];
char sqlstmt[300];
LPSTR szParmStrOut;
LPSTR szParmStrIn;
LPSTR szParmStrLast;
LPSTR str=szParms;
int dex;
int cParm;
ROWDATA FAR * rd;
BOOL fSemiProc=FALSE;

// Handle special case of a procedure name with a semi-colon
if(lstrcmp(szPipeName, szDROPPROCSEMI) == 0)
fSemiProc = TRUE;

//
// For each record selected, create a statement which can be executed by finding
// parameter markers and replacing them at run time.
//
for(dex=0; dex<cbCnt; dex++) {
_fmemset(sqlstmt, 0, sizeof(sqlstmt));
_fmemset(szUserSQLCopy, 0, sizeof(szUserSQLCopy));
lstrcpy(szUserSQLCopy, szUserSQL);
szParmStrOut = sqlstmt;
szParmStrIn = szUserSQLCopy;
szParmStrLast = szParmStrIn;
str = szParms;
rd = (ROWDATA FAR *)SendMessage(rs->hwndList, LB_GETITEMDATA, (WPARAM)xPipes[dex], 0L);
while(*str) {
cParm = lpatoi(str);
if(cParm > rs->cbColumns)
szWrite(ci->hwndOut,
GetidsString(idsInvalidParamValue, OutStr, MAXBUFF),
cParm, (LPSTR)szPipeName);
else if(szParmStrIn && *szParmStrIn) {
if((szParmStrIn = _fstrchr(szParmStrIn, '?'))) {
*szParmStrIn++ = '\0';
lstrcpy(szParmStrOut, szParmStrLast);
_fstrcat(szParmStrOut, rd->cd[cParm-1].szCols);
// Remove semi-colon for special case of drop procedure
if(fSemiProc) {
LPSTR str = _fstrchr(szParmStrOut, ';');
if(str)
*str = '\0';
}
szParmStrLast = szParmStrIn;
}
else
lstrcpy(szParmStrOut, szParmStrLast); // end of list
}
str += lstrlen(str) + 1;
}
if(*szParmStrLast)
_fstrcat(szParmStrOut, szParmStrLast);
ExecuteCmds(ci, sqlstmt);
}

return;
}