.ad 8
.bm 8
.fm 4
.bt $Copyright (c) 2000-2005 SAP AG$$Page %$
.tm 12
.hm 6
.hs 
.tt 1 $SQL$Project Distributed Database System$VPA07WC$
.tt 2 $$$
.tt 3 $BurkhardD$WINDOWS ENVIRONMENT FUNCTONS  $2001-06-26$
***********************************************************
.nf

.nf

.nf

    ========== licence begin  GPL
    Copyright (c) 2000-2005 SAP AG

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end
.fo

//
//   FreeBSD portions added by Kai Mosebach, 
//   For more informations see : http://www.komadev.de/sapdb
//

.fo


.fo
Module  :
=========
.sp
Purpose :
.CM *-END-* purpose -------------------------------------
Define  :
.CM *-END-* define --------------------------------------
Use     :
.CM *-END-* use -----------------------------------------
Synonym :
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  : BurkhardD
.sp
.cp 3
Created : 08-31-1993
.sp
.cp 3
Version : 1994-04-25
.sp
.cp 3
Release :  7.3    Date : 2001-06-26
.sp
Specification:
.CM *-END-* specification -------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Description:
.CM *-END-* description ---------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.nf
.oc _/1
Structure:
.CM *-END-* structure -----------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.CM -lll-
Code    :
#ifndef DEBUG
#line 63 "vpa07wc" 
#endif
/* next move to vpa00dlc */
#define API_SEC_LOGFILE "LogFile"
#define USESQLALLOCAT

/*#define AUTOFLUSH_TRACE*/

#define MIN_VPA(x,y) (x)<(y) ? (x) : (y)

#include <string.h>
#include <stdlib.h>
#include <time.h>
#include "vpr05IfCom_String.h"
#include "heo03.h"

#ifndef WIN32
#include <pwd.h>
#include "RunTime/RTE_IniFileHandling.h"
#include "SAPDBCommon/SAPDB_Names.h"
#else
#include <direct.h>
#endif
extern SDWORD api_dispatch;

SDWORD pa07blockmodus;
#ifdef ASYNCENABLED   
teo07_Mutex pa07CriticalSection=NULL;
#endif
#ifndef WIN
#define FAR
#endif
#define PA07_TRACERESET 	(0)
#define PA07_TRACEON    	(1)
#define PA07_TRACEOFF		(2)
#define PA07_TRACEINIT          (3)
#define PA07_TRACEDIALOG	(88)

#define PA07_MAXLEVEL 256
#define PA07_MAXBUFFER 1024

typedef struct {
    DWORD Id;
    SWORD level;
    long timetab[PA07_MAXLEVEL];   
    SWORD lazy_exit;
#ifdef WIN32
    HANDLE file_handle;   
#else
    FILE * file_handle;
#endif
    UCHAR buffer  [PA07_MAXBUFFER+1];
    UCHAR FAR szTmpStr[30];
} pa07TraceLocals;

#ifdef WIN32
extern  HANDLE s_hModule;
extern DLGPROC lpSendAHello;
api_global_tab pa07global[MAX_TASK];

/* wrapper for [Set|Get]DlgItemTextW */
UINT pa07GetDlgItemTextW (HWND hDlg, int nIDDlgItem, LPWSTR lpString, int nMaxCount);
BOOL pa07SetDlgItemTextW (HWND hDlg, int nIDDlgItem, LPCWSTR lpString);

#ifdef OLDTASK
HWND pa07GetODBCTaskWindow(HTASK hCurr);
#endif
void     PASCAL pa07CenterDialog    (HWND    hdlg);
BOOL PASCAL EXPORT ProcDebug(HWND, unsigned, WORD, LONG );
BOOL PASCAL EXPORT ProcAbout(HWND, unsigned int, WPARAM, LPARAM );
#else
/* from vpa82unix.c */
SWORD GetPrivateProfileString( UCHAR *lpszSection,
                               UCHAR *lpszEntry,
                               UCHAR *lpszDefault,
                               UCHAR *lpszReturnBuffer,
                               SWORD  cbReturnBuffer,
                               UCHAR *lpszFileName);
SWORD GetPrivateProfileStringW (SQLWCHAR  *lpszSection, 
                                SQLWCHAR  *lpszEntry, 
                                SQLWCHAR  *lpszDefault,
                                SQLWCHAR  *lpszReturnBuffer, 
                                SWORD      cbReturnBuffer, 
                                SQLWCHAR  *lpszFileName);

char *_strtime(char *tstr);
#endif
/* Prototypes --------------------------------------------------------------*/

pa07TraceLocals * pa07GetTLS(VOID);
UCHAR FAR *pa07Stack(VOID);
UCHAR FAR *pa07TracePrefix(pa07TraceLocals * lpTV);
VOID pa07TraceOutPut(pa07TraceLocals *lpTV, UCHAR FAR *buffer);
WORD FAR PCALL SendAHello(HWND ,UINT, int, DWORD );
SQLWCHAR* PA30TRIM(SQLWCHAR *LocalStr, SWORD len);
#ifndef WIN
API_RETCODE pa07GetDBNameFromDSN( UCHAR *szDSN,
                                  SWORD  cbDSN,
                                  UCHAR *serverdb_ptr,
                                  SWORD  serverdb_len, 
                                  UCHAR *servernode_ptr,
                                  SWORD  servernode_len );
#endif
extern  void PCALL s40gbyte ( UCHAR  *string_ptr,
                              SDWORD  pos, 
                              int     len,
                              UCHAR  *hex_ptr,
                              SWORD   dpos,
                              int     dlen,
                              UCHAR  *truncated );

SWORD api_trace_status = PA07_TRACERESET;

UCHAR pa07tracelevel [ 10 ];
SWORD pa07maxlevel = PA07_MAXLEVEL;
UCHAR pa07tracefilename [ 260 ];
#if !defined(WIN32) || !defined(AUTOFLUSH_TRACE)
FILE * pa07file_handle;
#endif

#ifdef ASYNCENABLED
#define PA07TLSINDEXEMPTY -1
tsp00_Int4 pa07TlsIndex=PA07TLSINDEXEMPTY;
extern DWORD pa09ThreadCount;
BOOL pa07tracerecursive=FALSE;
#else
pa07TraceLocals pa07TraceValues;
#endif


UCHAR FAR appexitmsg[] = "trace file won't open!!!!!";
UINT apdoptt();

#ifdef WIN32
SECURITY_ATTRIBUTES pa07sa={sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
OFSTRUCT OfStruct;
#endif

#define API_TRACE_OUTPUT(xbuffer) pa07TraceOutPut(lpTV, xbuffer)
				  /* gloval vars                */
#define API_TRACE_MAXCHAR 20

typedef struct {
    SQLWCHAR *dsn_ptr;
    SWORD  dsn_len;
    SQLWCHAR *userid_ptr;
    SWORD  userid_len;
    SQLWCHAR *passwd_ptr;
    SWORD  passwd_len;
    SQLWCHAR *serverdb_ptr;
    SWORD  serverdb_len;
    SQLWCHAR *servernode_ptr;
    SWORD  servernode_len;
    SWORD  casesensitive;
    SWORD  autocommit;
    SWORD  encrypt;
} profile_block;

/* apdallo() - API dependent function, allocate memory */
#ifndef USESQLALLOCAT
API_HANDLE apdallo ( DWORD size ) {

    API_HANDLE handle;
    UDWORD int_handle;

    API_TRACE(API_TR_ENTRY,"apdallo",0);
    API_TRACE(API_TR_DWORD,"size",&size);

    /* GlobalAlloc returns an "int" handle*/
    /* MUST have zero init, things depend on it!!!*/
    int_handle = (UDWORD)GlobalAlloc( (GMEM_MOVEABLE | GMEM_ZEROINIT),size );

    API_MEMCPY(&handle,&int_handle,sizeof(handle));

    if (handle == 0) {
        API_TRACE(API_TR_MSG,"GlobalAlloc failed.",0);
        handle = 0;
    }

    API_TRACE(API_TR_EXIT,"exit apdallo",0);
    API_TRACE(API_TR_HANDLE,"handle",&handle);

    return (handle);
} /* apdallo */


/* apdfree() - API dependent function, free memory */
VOID apdfree ( API_HANDLE handle ) {

    UDWORD int_handle;
#ifdef DEBUG   
    UINT fuFlags;
#endif
    API_TRACE(API_TR_ENTRY,"apdfree",0);
    API_TRACE(API_TR_HANDLE,"handle",&handle);

    API_MEMCPY(&int_handle,&handle,sizeof(int_handle));
#ifdef DEBUG
    fuFlags = GlobalFlags((HGLOBAL) int_handle);
    if (fuFlags == GMEM_INVALID_HANDLE) {
        UCHAR szLocal[256];
        API_SPRINTF(szLocal, "Invalid Handle (%#08lx) err = %ld.", int_handle, GetLastError());
        API_EXIT_MSG(szLocal);
    }
    if (fuFlags & GMEM_LOCKCOUNT) {
        UCHAR szLocal[256];
        API_SPRINTF(szLocal, "Handle (%#08lx) free with locks (%ld).", int_handle, fuFlags & GMEM_LOCKCOUNT);
        API_EXIT_MSG(szLocal);
    }
#endif
    GlobalFree((HGLOBAL) int_handle);

    API_TRACE(API_TR_EXIT,"apdfree",0);

    return;
} /* apdfree */

#else
/*
extern void sqlallocat (tsp00_Int4 length, void **objptr, 
	UCHAR *ok);
extern void sqlfree (void *objptr);
*/
API_HANDLE apdallo ( DWORD size ) {

    API_HANDLE handle;
    UCHAR * where;
    UCHAR ok;

    sqlallocat (size, (unsigned char**)&where, &ok);
    if (!ok)
        where = NULL;
    if (where == NULL) {
        API_TRACE(API_TR_MSG," error - malloc failed.",0);
        handle = 0;
        goto exit;
    }
    API_MEMSET(where,0,(int) size);     /* zero out storage */
    handle = where;
 exit:

    API_TRACE(API_TR_HANDLE,"apdallo",&handle);
    return (handle);

} /* apdallo */


/* apdfree() - API dependent function, free memory */
VOID apdfree ( API_HANDLE handle ) {
    sqlfree( handle );
    API_TRACE(API_TR_HANDLE,"apdfree",&handle);
    return;
} /* apdfree */
#endif
 
#ifndef SAPDB_FAST
#define PA07CASESTRING(buffer, x) \
case (x): {\
API_STRCPY(buffer, #x);\
break;\
}
#define PA07OUTPUT(buffer) \
API_TRACE_OUTPUT(pa07TracePrefix(lpTV));\
API_TRACE_OUTPUT(buffer);

#define BUFSIZE 1024

void pa07CloseTrace()
{
    pa07TraceLocals *lpTV = NULL;
    
    lpTV = (pa07TraceLocals*) pa09GetTLS(PA07TLS_TRACE);
    if (lpTV->file_handle != NULL) {
#if defined(WIN32) && defined(AUTOFLUSH_TRACE)
        CloseHandle(lpTV->file_handle);
#else
        fclose(lpTV->file_handle);
#endif
        lpTV->file_handle = NULL;
    };
} /* pa07CloseTrace */


VOID apdtrac( UWORD   type, 
              UCHAR  *name_ptr, 
              VOID   *ptr_ptr,
              SDWORD  len,
              SDWORD  pos)
{
    UCHAR           *buffer_ptr;
    UCHAR           *p;
    CHAR           *name;
    VOID            *ptr;
    SDWORD           i;
    CHAR            cpos[ 20 ];
    CHAR             hchar[ 20 ];
    SWORD            sword;
    UWORD            uword;
    UDWORD           udword;
    SDWORD           sdword;
    UCHAR            literal [300];
    pa07TraceLocals *lpTV;

    int              wstrLen;
    unsigned int     dummy;
    UCHAR            strPtr[512];
    unsigned int     strPtrLen;
    
    /* save the trace status to prevent recursive calls */
#ifdef ASYNCENABLED
    if (!pa07CriticalSection) {
        sqlcreatemutex(&pa07CriticalSection);
    }
    sqlbeginmutex(&pa07CriticalSection);
    /* don't trace the calls comming from the next commands */
    /* to prevent an endless loop */
    if (pa07tracerecursive) {
        sqlendmutex(&pa07CriticalSection);
        return;
    }
    pa07tracerecursive=TRUE;
    lpTV = (pa07TraceLocals *)pa09GetTLS(PA07TLS_TRACE);


    pa07tracerecursive=FALSE;
#else
#define sqlgetthreadid() (1)
    lpTV = &pa07TraceValues;
#endif

#ifndef SAPDB_FAST
    /* check heap */    
    if (type == API_TR_ENTRY || type == API_TR_EXIT)
          pr07CheckHeap (NULL); 
#endif
    
    if ( api_trace_status != PA07_TRACEDIALOG
         && api_trace_status != PA07_TRACEON
         && api_trace_status != PA07_TRACEOFF
         && api_trace_status != PA07_TRACEINIT) {
        API_EXIT_MSG("core overlay in apdtrac!!!!!");
    }
    if (api_trace_status == PA07_TRACEDIALOG
        || api_trace_status == PA07_TRACEINIT) {
        if (api_trace_status == PA07_TRACEDIALOG) {
            pa07maxlevel = pa07GetTraceLevel();
        }
        if (pa07maxlevel > 0) {
#if defined(WIN32) && defined(AUTOFLUSH_TRACE)
            lpTV->file_handle =
                CreateFile((UCHAR*) pa07GetTraceFileName(),\
                           GENERIC_WRITE,
                           FILE_SHARE_WRITE,
                           &pa07sa,
                           CREATE_ALWAYS, \
                           FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH,
                           NULL );
#else
            lpTV->file_handle = fopen( (CHAR*) pa07GetTraceFileName(), "w" );
            pa07file_handle   = lpTV->file_handle;
#endif
            if (lpTV->file_handle == 0) {
                API_EXIT_MSG("trace open failed....");
                api_trace_status = PA07_TRACEOFF;
            }
            else {
                time_t ltime;
                struct tm *ltm;
#if defined(WIN32) && defined(AUTOFLUSH_TRACE)
                CloseHandle(lpTV->file_handle);
                lpTV->file_handle = NULL;
#else
                fflush(lpTV->file_handle);
#endif
                api_trace_status = PA07_TRACEON;
                buffer_ptr = (UCHAR*) lpTV->buffer;
                API_SPRINTF( (CHAR*) buffer_ptr,
                             " TRACE-LEVEL : %d"CRLF, pa07maxlevel );
                PA07OUTPUT( buffer_ptr );
                time(&ltime);
                ltm = localtime(&ltime);
                strftime( (CHAR*) buffer_ptr,
                          sizeof(lpTV->buffer),
                          " START: %Y-%m-%d %H:%M:%S",
                          ltm);
                API_STRCAT(buffer_ptr, CRLF);
                PA07OUTPUT(buffer_ptr);
                name_ptr = (UCHAR*) "VERSION";
                ptr_ptr = API_DRIVER_VER;
                type = API_TR_STRING;
            }
        }
        else {
            api_trace_status = PA07_TRACEINIT; /* trace off */
        }
    } /* if 88, first time */

    if (api_trace_status == PA07_TRACEON) {
        if (lpTV->level <= pa07maxlevel || lpTV->lazy_exit || 
            type == API_TR_ENTRY || type == API_TR_EXIT) {
            buffer_ptr = (UCHAR FAR *) lpTV->buffer;
            if (name_ptr == NULL) {
                name = "** NULL **";
            }
            else
                name = (CHAR*) name_ptr;
            ptr = ptr_ptr;
            if (ptr == NULL && type != API_TR_ENTRY
                && type != API_TR_EXIT
                && type != API_TR_MSG) {
                API_SPRINTF((CHAR*) buffer_ptr," %s: is NULL"CRLF, name);
                PA07OUTPUT(buffer_ptr);
            }
            else {
                switch (type) {
                case (API_TR_ENTRY): {
                    char tstr[30];
                    if (lpTV->lazy_exit == 1) {
                        lpTV->lazy_exit = 0;
                        if (lpTV->level > 0)
                            lpTV->level--;
                    }
                    if (lpTV->level < PA07_MAXLEVEL)
                        lpTV->level++;
                    lpTV->timetab[lpTV->level] = clock();
#ifdef ASYNCENABLED
                    if (pa09ThreadCount > 1) {
                        API_SPRINTF((CHAR*) buffer_ptr,"#%d", lpTV->Id);
                        API_TRACE_OUTPUT(buffer_ptr);
                    }
#endif
                    if (lpTV->level == (SWORD) 1) {
                        _strtime(tstr);
                        API_SPRINTF( (CHAR*) buffer_ptr,
                                     " %03d>> ENTER: %s <%x> (%s) %s"CRLF,
                                     lpTV->level,
                                     name,
                                     sqlgetthreadid(),
                                     tstr,
                                     pa07Stack());
                    }
                    else {
                        API_SPRINTF( (CHAR*) buffer_ptr," %03d>> ENTER: %s %s"CRLF,
                                     lpTV->level, name, pa07Stack());
                    }
                    API_TRACE_OUTPUT(buffer_ptr);
                    break;
                }
                case (API_TR_EXIT): {
                    double t;
                    char tstr[30];
                    char difftstr[30];
                    if (lpTV->lazy_exit == 1) {
                        lpTV->lazy_exit = 0;
                        if (lpTV->level > 0)
                            lpTV->level--;
                    }
#ifdef WIN32
                    t = clock() - lpTV->timetab[lpTV->level];
#else
                    t = (float) (clock() - lpTV->timetab[lpTV->level]) / 1000;
#endif
#ifndef FREEBSD
                    gcvt( t, 15, difftstr);
#else
// this is our workaround for the missing ecvt / gcvt functionality in the 
// FreeBSD libc implementation ...
		            sprintf(difftstr, "%.15f", t);	// Its ANSI C
#endif

#ifdef ASYNCENABLED
                    if (pa09ThreadCount > 1) {
                        API_SPRINTF((CHAR*) buffer_ptr,"#%d", lpTV->Id);
                        API_TRACE_OUTPUT(buffer_ptr);
                    }
#endif
                    API_SPRINTF((CHAR*) buffer_ptr,
                                " %03d<< EXIT: %s", lpTV->level, name);
                        if (lpTV->level == 0)
                            {
                                puts (" ");
                            }
                    API_TRACE_OUTPUT(buffer_ptr);
                    if (lpTV->level == 1) {
                        _strtime(tstr);
                        API_SPRINTF((CHAR*) buffer_ptr, " (%s)", tstr);
                        API_TRACE_OUTPUT(buffer_ptr);
                    }
                    if (t > 0) {
                        API_SPRINTF((CHAR*) buffer_ptr," (%s ms)", difftstr);
                        API_TRACE_OUTPUT(buffer_ptr);
                    }
                    API_STRCPY(buffer_ptr, CRLF);   
                    API_TRACE_OUTPUT(buffer_ptr);
                    lpTV->lazy_exit = 1;
                    break;
                }
                } /* switch */
                /* unwrap tpr05_String */
                if (type == API_TR_TPR05STRING) {
                    if (((tpr05_String *) ptr)->encodingType == sp77encodingAscii) {
                        strPtrLen = MIN_VPA (((tpr05_String *) ptr)->cbLen, sizeof (strPtr) - 1);
                        API_STRNCPY (strPtr, ((tpr05_String *) ptr)->rawString,
                                     strPtrLen);
                        strPtr[strPtrLen] = '\0';
                        ptr  = strPtr;
                        type = API_TR_STRING;
                    }
                    else  {  /* sp77nativeUnicodeEncoding() */
                        strPtrLen = MIN_VPA (((tpr05_String *) ptr)->cbLen, sizeof (strPtr) - 2);
                        strPtrLen /= sizeof (tsp81_UCS2Char);
                        sp81UCS2strncpy ((tsp81_UCS2Char *) strPtr, 
                                         (tsp81_UCS2Char *) ((tpr05_String *) ptr)->rawString,
                                         strPtrLen);
                        strPtrLen *= sizeof (tsp81_UCS2Char);
                        strPtr[strPtrLen]   = '\0';         /* what happens if             */
                        strPtr[strPtrLen+1] = '\0';         /* sizeof(tsp81_UCS2Char) > 2? */
                        ptr  = strPtr;
                        type = API_TR_WSTRING;
                    }
                }

                /* if ptr is WCHAR, translate to ASCII */
                if (type == API_TR_WSTRING) {
                    wstrLen = sp81UCS2strlen ((tsp81_UCS2Char*) ptr);
                    strPtrLen = MIN_VPA (wstrLen, sizeof (strPtr) - 1);
                    sp81UCS2toASCII (strPtr, wstrLen, &dummy,
                                     (tsp81_UCS2Char*) ptr,
                                     strPtrLen,
                                     sp77nativeUnicodeEncoding() == sp77encodingUCS2Swapped);
                    strPtr[strPtrLen] = '\0';
                    ptr  = strPtr;
                    len  = (SDWORD) API_STRLEN (strPtr);
                    type = API_TR_STRING;
                }
                if (lpTV->level <= pa07maxlevel) {
                    switch (type) {
                    case (API_TR_BUFFER): {
                        CHAR clit [ (API_TRACE_MAXCHAR+1)*3 ];
                        CHAR hlit [ (API_TRACE_MAXCHAR+1)*3 ];
                        CHAR cchar  [ 20 ];
                        API_SPRINTF( (CHAR*) buffer_ptr,
                                     " buffer from %d to %d"CRLF, pos, len );
                        PA07OUTPUT(buffer_ptr);
                        if (ptr != NULL) {
                            p = (UCHAR FAR*) ptr+pos;
                            API_STRCPY(buffer_ptr,"");
                            API_STRCPY(hlit,"");
                            API_STRCPY(clit,"");
                            for ( i=1; i <= len; i++) {
                                API_SPRINTF(cpos, "%3d", i);
                                if (isprint(*p))
                                    API_SPRINTF(cchar, "%3c", *p);
                                else
                                    API_SPRINTF(cchar, "%3c", '.');
                                API_SPRINTF(hchar, " %02x", *p);
                                p++;
                                API_STRCAT(buffer_ptr, cpos);
                                API_STRCAT(hlit, hchar);
                                API_STRCAT(clit, cchar);
                                if (! (i % API_TRACE_MAXCHAR)) {
                                    API_STRCAT (buffer_ptr, CRLF);
                                    PA07OUTPUT(buffer_ptr);
                                    API_STRCAT (hlit, CRLF);
                                    PA07OUTPUT((UCHAR*) hlit);
                                    API_STRCAT (clit, CRLF);
                                    PA07OUTPUT((UCHAR*) clit);

                                    API_STRCPY(buffer_ptr, "");
                                    API_STRCPY(hlit, "");
                                    API_STRCPY(clit, "");
                                }
                            }
                            if (buffer_ptr) {
                                API_STRCAT(buffer_ptr, CRLF);
                                PA07OUTPUT(buffer_ptr);
                            }
                            if (hlit[0]) {
                                API_STRCAT(hlit, CRLF);
                                PA07OUTPUT((UCHAR*) hlit);
                            }
                            if (clit[0]) {
                                API_STRCAT(clit, CRLF);
                                PA07OUTPUT((UCHAR*) clit);
                            }
                        }
                        else {
                            API_SPRINTF((CHAR*) buffer_ptr,
                                        "*** is NULL ***"CRLF, pos, len);
                            API_TRACE_OUTPUT(buffer_ptr);
                        }
                        break;
                    }
                    case (API_TR_STRING): {}
                    case (API_TR_ODBC_STRING): {
                        UCHAR FAR *p=(UCHAR*) ptr;
                        if (type == API_TR_ODBC_STRING) {
                            if (len == SQL_NULL_DATA) {
                                API_SPRINTF((CHAR*) buffer_ptr,
                                            " %s: is NULL"CRLF, name);
                                PA07OUTPUT(buffer_ptr);
                            }
                            else {
                                if (len == SQL_NTS) {
                                    len = (SDWORD) API_STRLEN(p);
                                }
                            }
                        }
                        else {
                            len = (SDWORD) API_STRLEN((CHAR*) p);
                        }
                        API_SPRINTF((CHAR*) buffer_ptr," %s: ", name);
                        PA07OUTPUT(buffer_ptr);
                        for(;len > 0;len-=PA07_MAXBUFFER,p+=PA07_MAXBUFFER) {
                            int clen = (len > PA07_MAXBUFFER) ? PA07_MAXBUFFER : len;
                            API_MEMCPY(buffer_ptr, p, clen);
                            buffer_ptr[clen] = '\0';			      
                            API_TRACE_OUTPUT(buffer_ptr);
                            if (len > PA07_MAXBUFFER)
                                API_TRACE_OUTPUT((UCHAR*) CRLF);
                        }	
                        API_TRACE_OUTPUT((UCHAR*) CRLF);
                        break;
                    }
                    case (API_TR_PARSID): {
                        apdhex (ptr, 12, literal, 255);
                        API_SPRINTF((CHAR*) buffer_ptr,
                                    " %s: %s"CRLF, name, literal);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_UCHAR): {
                        API_SPRINTF((CHAR*) buffer_ptr,
                                    " %s: %x"CRLF, name, * (char FAR *) ptr);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_SCHAR): {
                        API_SPRINTF((CHAR*) buffer_ptr,
                                    " %s: %x"CRLF, name, * (char FAR *) ptr);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_WORD): {}
                    case (API_TR_UWORD): {
                        WORD l;
                        API_MEMCPY(&l, ptr, sizeof(WORD));
                        API_SPRINTF((CHAR*) buffer_ptr," %s: %hu"CRLF, name, l);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_SWORD): {
                        SWORD l;
                        API_MEMCPY(&l, ptr, sizeof(SWORD));
                        API_SPRINTF((CHAR*) buffer_ptr," %s: %hd"CRLF, name, l);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_DWORD): {}
                    case (API_TR_UDWORD): {
                        DWORD l;
                        API_MEMCPY(&l, ptr, sizeof(DWORD));
                        API_SPRINTF((CHAR*) buffer_ptr," %s: %lu"CRLF, name, l);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_SDWORD): {
                        SDWORD l;
                        API_MEMCPY(&l, ptr, sizeof(SDWORD));
                        API_SPRINTF((CHAR*) buffer_ptr," %s: %ld"CRLF, name, l);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_SDOUBLE): {
                        SWORD trace_status=api_trace_status;
                        api_trace_status = PA07_TRACEOFF;
                        pa08flt(literal,  * ( double FAR *) ptr, SQL_DOUBLE);
                        api_trace_status=trace_status;
                        API_SPRINTF((CHAR*) buffer_ptr," %s: %s"CRLF, name, literal);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_SFLOAT): {
                        SWORD trace_status=api_trace_status;
                        api_trace_status = PA07_TRACEOFF;
                        pa08flt(literal,  * ( float FAR *) ptr, SQL_REAL);
                        api_trace_status=trace_status;
                        API_SPRINTF((CHAR*) buffer_ptr," %s: %s"CRLF, name, literal);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_LDOUBLE): {
                        API_SPRINTF((CHAR*) buffer_ptr, " can't trace long double yet.");
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_PTR): {
                        API_SPRINTF( (CHAR*) buffer_ptr," %s: %#08lx"CRLF,
                                     name, *(char**) ptr);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_HANDLE): {
                        API_SPRINTF((CHAR*) buffer_ptr," %s: %#08lx"CRLF,
                                    name, *(unsigned long*) ptr);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_HWND): {
                        API_SPRINTF((CHAR*) buffer_ptr," %s: %#04x"CRLF,
                                    name, *( unsigned int*) ptr);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_RETCODE): {
                        switch ( *((RETCODE*) ptr)) {
                            PA07CASESTRING(literal, SQL_ERROR);
                            PA07CASESTRING(literal, SQL_INVALID_HANDLE);
                            PA07CASESTRING(literal, SQL_NEED_DATA);
                            PA07CASESTRING(literal, SQL_NO_DATA_FOUND);
                            PA07CASESTRING(literal, SQL_SUCCESS);
                            PA07CASESTRING(literal, SQL_STILL_EXECUTING);
                            PA07CASESTRING(literal, SQL_SUCCESS_WITH_INFO);
                        default: {
                                API_STRCPY(literal,(UCHAR*) "** unknown! **");
                                break;
                            }
                        }
                        API_SPRINTF( (CHAR*) buffer_ptr," %s: %d (%s)"CRLF,
                                     name, * ( RETCODE*) ptr, (char*) literal);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_SQLSTATE): {
                        API_SPRINTF((CHAR*) buffer_ptr," %s: %-5.5s"CRLF,
                                    name, (char*) ptr);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_API_ESQ_BLOCK): {
                        API_SPRINTF((CHAR*) buffer_ptr,
                                    " %s (esq_sql_code: %ld number_rows_modified: %ld)"CRLF, 
                                    name,
                                    ((api_esq_block*) ptr) -> esq_sql_code,
                                    ((api_esq_block*) ptr) -> number_rows_modified);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_API_RETCODE): {
                        switch ( * (API_RETCODE*) ptr) {
                            PA07CASESTRING(literal, API_OK);
                            PA07CASESTRING(literal, API_NOT_OK);
                            PA07CASESTRING(literal, API_TRUNCATE);
                            PA07CASESTRING(literal, API_DATA_LOSS);
                            PA07CASESTRING(literal, API_NOT_NUMBER);
                            PA07CASESTRING(literal, API_NOT_DATE);
                            PA07CASESTRING(literal, API_FEW_BOUNDS);
                            PA07CASESTRING(literal, API_NEED_DATA);
                            PA07CASESTRING(literal, API_NO_DATA_FOUND);
                        default: {
                                API_STRCPY(literal,(UCHAR*) "** unknown! **");
                                break;
                            }
                        }
                        API_SPRINTF((CHAR*) buffer_ptr," %s: %d (%s)"CRLF,
                                    name, *(API_RETCODE*) ptr,
                                    (UCHAR*) literal);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_GETINFO): {
                        uword = *((UWORD*) ptr);
                        pa90GetInfoAttrAsString( uword, (CHAR*) literal );
                        API_SPRINTF((CHAR*) buffer_ptr,
                                    " %s: %d (%s)"CRLF,
                                    name, uword, literal);
                        PA07OUTPUT(buffer_ptr);
                        break;       
                    }
                    case (API_TR_DESCTYPE): {
                        sword = *(SWORD*) ptr;
                        pa90DescTypeAsString( sword, (CHAR*) literal );
                        API_SPRINTF((CHAR*) buffer_ptr,
                                    " %s: %d (%s)"CRLF,
                                    name, sword, literal);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_COLATTR): {
                        uword = *((UWORD*) ptr);
                        pa90ColAttrAsString( uword, (CHAR*) literal );
                        API_SPRINTF((CHAR*) buffer_ptr,
                                    " %s: %d (%s)"CRLF,
                                    name, uword, literal);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_STMTATTR): {
                        sdword = *((SDWORD*) ptr);
                        pa90StmtAttrAsString( sdword, (CHAR*) literal );
                        API_SPRINTF((CHAR*) buffer_ptr,
                                    " %s: %d (%s)"CRLF,
                                    name, sdword, literal);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_SQLTYPE): {
                        sword = *((SWORD*) ptr);
                        pa90SQLTypeAsString( sword, (CHAR*) literal );
                        API_SPRINTF((CHAR*) buffer_ptr,
                                    " %s: %d (%s)"CRLF,
                                    name, sword, literal);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_CTYPE): {
                        sword = *((SWORD*) ptr);
                        pa90CTypeAsString( sword, (CHAR*) literal );
                        API_SPRINTF((CHAR*) buffer_ptr,
                                    " %s: %d (%s)"CRLF,
                                    name, sword, literal);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_ENVATTR): {
                        sword = *((SWORD*) ptr);
                        pa90EnvAttrAsString( sword, (CHAR*) literal );
                        API_SPRINTF((CHAR*) buffer_ptr,
                                    " %s: %d (%s)"CRLF,
                                    name, sword, literal);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_CONNATTR): {
                        sdword = *((SDWORD*) ptr);
                        pa90ConnAttrAsString( sdword, (CHAR*) literal );
                        API_SPRINTF((CHAR*) buffer_ptr,
                                    " %s: %d (%s)"CRLF,
                                    name, sdword, literal);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_UPDATEABLE): {
                        sdword = *((SDWORD*) ptr);
                        pa90UpdateableAsString( sdword, (CHAR*) literal );
                        API_SPRINTF((CHAR*) buffer_ptr,
                                    " %s: %d (%s)"CRLF,
                                    name, sdword, literal);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_DIAGFIELD): {
                        sword = *((SWORD*) ptr);
                        pa90DiagFieldAsString( sword, (CHAR*) literal );
                        API_SPRINTF((CHAR*) buffer_ptr,
                                    " %s: %d (%s)"CRLF,
                                    name, sword, literal);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_CURSORTYPE): {
                        udword = *((UDWORD*) ptr);
                        pa90CursorTypeAsString( udword, (CHAR*) literal );
                        API_SPRINTF((CHAR*) buffer_ptr,
                                    " %s: %d (%s)"CRLF,
                                    name, udword, literal);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_FETCHTYPE): {
                        uword = *((UWORD*) ptr);
                        pa90FetchTypeAsString( uword, (CHAR*) literal );
                        API_SPRINTF((CHAR*) buffer_ptr,
                                    " %s: %d (%s)"CRLF,
                                    name, uword, literal);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_OPTYPE): {
                        uword = *((UWORD*) ptr);
                        pa90OpTypeAsString( uword, (CHAR*) literal );
                        API_SPRINTF((CHAR*) buffer_ptr,
                                    " %s: %d (%s)"CRLF,
                                    name, uword, literal);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }                    
                    case (API_TR_MSG): {
                        API_SPRINTF((CHAR*) buffer_ptr," %s"CRLF, name);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    case (API_TR_LASTERROR): {
                        LPVOID lpMsgBuf;
                        API_SPRINTF((CHAR*) buffer_ptr," %s"CRLF, name);
                        PA07OUTPUT(buffer_ptr);
#ifdef WIN32
                        FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER
                                       | FORMAT_MESSAGE_FROM_SYSTEM,
                                       NULL,
                                       len,
                                       MAKELANGID(LANG_NEUTRAL,
                                                  SUBLANG_DEFAULT),
                                       /* Default language */
                                       (LPTSTR) &lpMsgBuf, 0, NULL );
                        PA07OUTPUT(lpMsgBuf);
                        LocalFree(lpMsgBuf);
#endif
                        API_SPRINTF((CHAR*) buffer_ptr, CRLF, name);
                        PA07OUTPUT(buffer_ptr);
                        break;
                    }
                    }
                }
            }
        }
    }
#ifdef ASYNCENABLED   
    sqlendmutex(&pa07CriticalSection);
#endif
    return;
} /* apdtrac */


#endif
/* apdsnap() - API dependent function, snap dump structures */
/*             this is a debugging function that can be     */
/*             called to make a formatted dump of all the   */
/*             connect blocks (dbcs) and statement blocks   */
/*             (stmts) hung off of the given environment    */
/*             block (env).  Output sent to printf().       */

VOID apdsnap (henv)

    HENV henv;

{

    API_TRACE(API_TR_ENTRY,"apdsnap",0);
    API_TRACE(API_TR_HANDLE,"henv",&henv);

    API_TRACE(API_TR_MSG," apdsnap disabled under Windows",0);

    API_TRACE(API_TR_EXIT,"apdsnap",0);

    return;

} /* apdsnap */

#ifdef WIN32
void PASCAL pa07CenterDialog(HWND hdlg)
{
    RECT  rcParent;                         /* Parent window client rect*/
    RECT  rcDlg;                            /* Dialog window rect*/
    int   nLeft, nTop;                      /* Top-left coordinates*/
    int   cWidth, cHeight;                  /* Width and height*/

    /* Get frame window client rect in screen coordinates*/
    GetWindowRect(GetDesktopWindow(), &rcParent);

    /* Determine the top-left point for the dialog to be centered*/
    GetWindowRect(hdlg, &rcDlg);
    cWidth  = rcDlg.right  - rcDlg.left;
    cHeight = rcDlg.bottom - rcDlg.top;
    nLeft   = rcParent.left + 
        (((rcParent.right  - rcParent.left) - cWidth ) / 2);
    nTop    = rcParent.top  +
        (((rcParent.bottom - rcParent.top ) - cHeight) / 2);
    if (nLeft < 0) nLeft = 0;
    if (nTop  < 0) nTop  = 0;

    /* Place the dialog*/
    MoveWindow(hdlg, nLeft, nTop, cWidth, cHeight, TRUE);
    return;
}
#endif

SQLWCHAR* PA30TRIM (SQLWCHAR *LocalStr, SWORD len)
{
    int j;
    j = sp81UCS2strlen ((tsp81_UCS2Char*) LocalStr);
    if (j >= len)
        j = len-1;

    API_MEMSET (&LocalStr[j], 0, sizeof (SQLWCHAR));
/*     *(LocalStr+j+1) = '\0'; */
    return (LocalStr);
}

#ifdef WIN32
BOOL FAR PASCAL EXPORT ProcUser( 
                                HWND hDlg,
                                UINT message,
                                WPARAM wParam,
                                LPARAM lParam)
{
    SWORD count;
    int idControl=API_USEROK;
    static profile_block *useropt;
    static BOOL IsInit=FALSE;
    DLGPROC dlgprc;  
    UCHAR Msg[512];

/*    pa03Set3dDialog(hDlg, message, wParam, lParam); */
    API_TRACE(API_TR_UDWORD, "ProcUser message", &message);
    API_TRACE(API_TR_UDWORD, "ProcUser wParam", &wParam);
    switch (message) {
    case WM_INITDIALOG: {
        API_TRACE(API_TR_UWORD, "ProcUser WM_INITDIALOG wParam", &wParam);
        useropt = (profile_block *)lParam;
        pa07CenterDialog(hDlg);
        AppendMenu(GetSystemMenu(hDlg, FALSE), MF_SEPARATOR, 0, "");
        AppendMenu(GetSystemMenu(hDlg, FALSE),
                   MF_ENABLED | MF_STRING, CMD_ABOUT,
                   "&About ...");
#ifdef _UNICODE_ODBC
        API_SPRINTF(Msg, API_PROD_NAME" %s (Unicode)", VERSION_MMC_STR_SP100);
#else
        API_SPRINTF(Msg, API_PROD_NAME" %s", VERSION_MMC_STR_SP100);
#endif
        SetWindowText(hDlg, Msg);
        pa07SetDlgItemTextW (hDlg, API_USERID, useropt->userid_ptr);
        pa07SetDlgItemTextW (hDlg, API_PASSWORD, useropt->passwd_ptr);
        pa07SetDlgItemTextW (hDlg, API_SERVERDB, useropt->serverdb_ptr);
        pa07SetDlgItemTextW (hDlg, API_SERVERNODE, useropt->servernode_ptr);
        if (*(useropt->servernode_ptr) == '\0')
            idControl = API_SERVERNODE;
        else if (*(useropt->serverdb_ptr) == '\0')
            idControl = API_SERVERDB;
        else if (*(useropt->userid_ptr) == '\0')
            idControl = API_USERID;
        else if (*(useropt->passwd_ptr) == '\0')
            idControl = API_PASSWORD;

        if (useropt->encrypt == SQL_ATTR_ENCRYPT_OFF)
          CheckDlgButton (hDlg, API_ENCRYPT, BST_UNCHECKED);
        else
          CheckDlgButton (hDlg, API_ENCRYPT, BST_CHECKED);

        SetFocus(GetDlgItem(hDlg, idControl));
        
        IsInit = TRUE;
        return FALSE;
        break;
    }
    case WM_CLOSE: {
        EndDialog(hDlg, FALSE);
        return TRUE;
        break;
    }
    case WM_COMMAND: {
#ifdef WIN32
        HWND hwndCtl = (HWND) lParam;
        UWORD wNCode = (UWORD) HIWORD(wParam);
        int wParm = (int) LOWORD(wParam);
#else
        HWND hwndCtl = (HWND) LOWORD(lParam);
        UWORD wNCode = (HWND) HIWORD(lParam);
        int wParm = wParam;
#endif

        API_TRACE(API_TR_UWORD, "ProcUser WM_COMMAND wParam", &wParam);
        switch (wParm) {
	    case API_PASSWORD: {}
	    case API_USERID: {
              tsp81_UCS2Char qouteW, blankW;
              UCHAR c;
              unsigned int dummy;

              /* need '"' and ' ' in UCS2 later */
              c = '"';
              sp81ASCIItoUCS2 ( &qouteW, 1,
                                sp77nativeUnicodeEncoding () == sp77encodingUCS2Swapped,
                                &dummy, &c, 1);
              c = ' ';
              sp81ASCIItoUCS2 ( &blankW, 1,
                                sp77nativeUnicodeEncoding () == sp77encodingUCS2Swapped,
                                &dummy, &c, 1);

            if (wNCode == EN_CHANGE && IsInit) {
                SQLWCHAR szLocalStr[256];
                SWORD i;
                count = pa07GetDlgItemTextW (hDlg, wParm,
                                             szLocalStr,
                                             sizeof(szLocalStr) / sizeof(SQLWCHAR));
                if (count > 0) {
                    for (i=0; i < count && ((tsp81_UCS2Char*) szLocalStr)[i].s == blankW.s; i++);
                    if (((tsp81_UCS2Char*) szLocalStr)[i].s != qouteW.s) {
                        LRESULT dwResult;
                        aputoupW ((tsp81_UCS2Char*) szLocalStr);
                        IsInit = FALSE;
                        /* store position of cursor */ 
                        dwResult = SendMessage(hwndCtl, EM_GETSEL, 0, 0L);
                        /* update edit box */
                        SendMessageW( hwndCtl,
                                     WM_SETTEXT,
                                     0,
                                     (LPARAM) szLocalStr);
                        /* restore position of cursor */
#ifdef WIN32
                        SendMessage( hwndCtl,
                                     EM_SETSEL,
                                     (WPARAM) LOWORD(dwResult),
                                     (LPARAM) HIWORD(dwResult));
#else
                        SendMessage(hwndCtl, EM_SETSEL, 0, dwResult);
#endif
                        IsInit = TRUE;
                    }
                }
            }
            return FALSE;
            break;	       
	    }
	    case API_USEROK: {
            SQLWCHAR szLocalStr[256];
            SQLWCHAR *ptr;
            count = pa07GetDlgItemTextW (hDlg, API_USERID,
                                         szLocalStr,
                                         sizeof(szLocalStr)/sizeof(SQLWCHAR));
            ptr = PA30TRIM (szLocalStr, useropt->userid_len);
            sp81UCS2strcpy (useropt->userid_ptr, ptr);
/*             API_STRCPY(useropt->userid_ptr, ptr);	        */
            count = pa07GetDlgItemTextW (hDlg, API_PASSWORD,
                                         szLocalStr,
                                         sizeof(szLocalStr)/sizeof(SQLWCHAR));
            ptr = PA30TRIM (szLocalStr, useropt->passwd_len);
            sp81UCS2strcpy (useropt->passwd_ptr, ptr);
/*             API_STRCPY(useropt->passwd_ptr, ptr);	        */
            count = pa07GetDlgItemTextW (hDlg, API_SERVERDB,
                                         useropt->serverdb_ptr,
                                         useropt->serverdb_len);
            count = pa07GetDlgItemTextW (hDlg, API_SERVERNODE,
                                         useropt->servernode_ptr,
                                         useropt->servernode_len);

            /* http://pts:1080/webpts?wptsdetail=yes&ErrorType=1&ErrorID=1133247 */
            if (IsDlgButtonChecked(hDlg, API_ENCRYPT))
              useropt->encrypt = SQL_ATTR_ENCRYPT_SSL;
            else
              useropt->encrypt = SQL_ATTR_ENCRYPT_OFF;

            EndDialog(hDlg, TRUE);
            return TRUE;
            break;
	    }
        case IDCANCEL: /* Close Dialog when escape is pressed (PTS 1105740) */
	    case API_USERBAIL: {
            EndDialog(hDlg, FALSE);
            return TRUE;
            break;
	    }
        } /* switch wParam */
        break;
    } /* WM_COMMAND */
    case WM_SYSCOMMAND: {
        switch (wParam) {
	    case CMD_ABOUT: {
            DialogBox(s_hModule, "ABOUTBOX", hDlg, ProcAbout);
            FreeProcInstance((FARPROC) dlgprc); 
            return FALSE;
	    }
        }
        break;
    } /* WM_SYSCOMMAND */
    } /* switch message */
    return FALSE;
}

UINT  apdoptt()
{
    INT_PTR iRet;
    HWND hwnd = 0;
    DLGPROC dlgprc;  
    if (FindWindow("#32770", "LiveCache ODBC Trace") != NULL) {
        ProcDebug(NULL, WM_INITDIALOG, 0, 0);
        iRet = TRUE;
    }
    else {
        hwnd = GetActiveWindow();
        dlgprc = (DLGPROC) MakeProcInstance(ProcDebug,s_hModule);
        iRet = DialogBox(s_hModule, "DEBUGBOX", hwnd, dlgprc);
        FreeProcInstance((FARPROC) dlgprc); 
    }
    if (iRet == TRUE) {
        if (pa07tracefilename != NULL) {
            iRet = atoi(pa07tracelevel);
            if (iRet == 0) {
                iRet=PA07_MAXLEVEL;
            }
        }
    }
    else {
        if (iRet == FALSE) {
            iRet = 0;
        }
        else {
            if (iRet == -1) {
                API_EXIT_MSG(" Trace Dialog Box Failed!");
                iRet = 0;
            }
        }
    }
    return((UINT) iRet);       /* ia 64 cast */
}; /* apdoptt */
#endif

/* get serverdb and servername from DSB */
API_RETCODE apdgdbn( /* UCHAR  *szDSN, SWORD cbDSN, */
                     tpr05_String *DSN,
                     UCHAR  *serverdb_ptr, 
                     SWORD   serverdb_len,
                     UCHAR  *servernode_ptr,
                     SWORD   servernode_len)
{
    UCHAR szDSN[1024];
    SWORD cbDSN = sizeof (szDSN);
    tsp00_Uint4 destBytesWritten, srcBytesParsed;

    SWORD len;
    UCHAR FAR *ptr;
    UCHAR profstr[255];
    API_RETCODE api_retcode=API_OK;    
    BOOL ret;
    SWORD deflt_srvdb=API_FALSE;   /* Default read ServerDB TRUE/FALSE   */
    SWORD deflt_srvnd=API_FALSE;   /* Default read ServerNode TRUE/FALSE */   
    API_TRACE(API_TR_ENTRY,"apdgdbn",0);

    /* This routine only supports a DSN that can be transformed to ASCII */
    sp78convertString (sp77encodingAscii,
                       szDSN, cbDSN,
                       &destBytesWritten,
                       TRUE,
                       DSN->encodingType,
                       DSN->rawString,
                       DSN->cbLen,
                       &srcBytesParsed);

    ret = pa08GetODBCProfile( szDSN,
                              (UCHAR*) "ServerDB",
                              profstr,
                              sizeof(profstr),
                              &len,
                              &deflt_srvdb, NULL);
    API_TRACE(API_TR_STRING, "profstr", profstr);
    if ( !ret ) {
#ifndef WIN	    
        api_retcode = pa07GetDBNameFromDSN( szDSN,
                                            cbDSN,
                                            serverdb_ptr,
                                            serverdb_len,
                                            servernode_ptr,
                                            servernode_len);
#else
        api_retcode = API_NOT_OK;
#endif   
    } else {
        ptr = (UCHAR FAR *)API_STRCHR(profstr, PA_NODE_SEP);
        if (ptr == NULL) {
            if (serverdb_len > len) {
                if (serverdb_ptr[0] == '\0') {
                    API_STRCPY(serverdb_ptr, profstr);
                    ret = pa08GetODBCProfile( szDSN,
                                              (UCHAR*) "ServerNode",
                                              servernode_ptr,
                                              servernode_len,
                                              &len,
                                              &deflt_srvnd, NULL);
                    if (!ret) {
                        if (servernode_ptr[0] == '?') {
                            servernode_ptr[0] = '\0';
                            api_retcode = API_OK;		     
                        }
                        else
                            api_retcode = API_NOT_OK;
                    } else { /* Check defaults ServerDB and ServerNode */
                        if ( (deflt_srvdb==API_FALSE)
                             && (deflt_srvnd==API_TRUE))
                            servernode_ptr[0] = '\0';
                    }
                }
            }
            else
                api_retcode = API_NOT_OK;
        }
        else {           
            *ptr = '\0';
            if (servernode_len > (SWORD) API_STRLEN(profstr)) {
                if (servernode_ptr[0] == '\0')
                    API_STRCPY(servernode_ptr, profstr);
                if (serverdb_len > (SWORD)API_STRLEN(ptr+1))
                    if (serverdb_ptr[0] == '\0')
                        API_STRCPY(serverdb_ptr, ptr+1);
                    else
                        api_retcode = API_NOT_OK;
            }
            else
                api_retcode = API_NOT_OK;
        }
        API_TRACE(API_TR_STRING, "serverdb", serverdb_ptr);
        API_TRACE(API_TR_STRING, "servernode", servernode_ptr);
    }   
    API_TRACE(API_TR_EXIT,"apdgdbn",0);
    API_TRACE(API_TR_API_RETCODE,"api_retcode",&api_retcode);
    return(api_retcode);
} /* apdgdbn */


API_RETCODE pa07GetDBNameFromDSN( UCHAR *szDSN, 
                                  SWORD  cbDSN, 
                                  UCHAR *serverdb_ptr, 
                                  SWORD  serverdb_len,
                                  UCHAR *servernode_ptr, 
                                  SWORD  servernode_len)
{
    API_RETCODE api_retcode;
    UCHAR FAR * ptr;
    api_retcode = API_OK;
    API_TRACE(API_TR_ENTRY,"pa07GetDBNameFromDSN",0);
    API_TRACE(API_TR_SWORD, "serverdb_len", &serverdb_len);
    API_TRACE(API_TR_SWORD, "servernode_len", &servernode_len);
    if (szDSN[0] == (UCHAR) NULL || cbDSN == SQL_NULL_DATA) {
        if (serverdb_len > 1) {
            serverdb_ptr[0] = PA_NODE_SEP;
            serverdb_ptr[1] = 0;
        }
        else 
            api_retcode = API_NOT_OK;
    }
    API_STRCPY(servernode_ptr, szDSN);
    ptr = (UCHAR*) API_STRCHR(servernode_ptr, PA_NODE_SEP);
    if (ptr != NULL) {
        *ptr = '\0';
        API_STRCPY(serverdb_ptr, ptr+1);
    } else {
        api_retcode = API_NOT_OK;
        API_STRCPY(serverdb_ptr, "");
    }
    API_TRACE(API_TR_STRING, "servernode_ptr", servernode_ptr);
    API_TRACE(API_TR_STRING, "serverdb_ptr", serverdb_ptr);
    API_TRACE(API_TR_EXIT, "pa07GetDBNameFromDSN",0);
    API_TRACE(API_TR_API_RETCODE, "api_retcode",&api_retcode);
    return(api_retcode);
} /* pa07GetDBNameFromDSN */


#ifdef WIN32
BOOL FAR PASCAL EXPORT ProcDebug(hDlg, message, wParam, lParam)
    HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    int count;
    SWORD level;
    UCHAR szModuleName[260];
    switch (message) {
	case WM_INITDIALOG: {
        pa07CenterDialog(hDlg);  /* Center dialog*/
        GetPrivateProfileString((UCHAR*) API_TR_PROFENTRY,
                                (UCHAR*) API_SEC_LOGFILE,
                                (UCHAR*) "trace.log",
                                (UCHAR*) pa07tracefilename,
                                sizeof(pa07tracefilename),
                                (UCHAR*) "sql-db.ini");
        GetPrivateProfileString((UCHAR*) API_TR_PROFENTRY,
                                (UCHAR*) API_SEC_TRACELEVEL,
                                (UCHAR*) "256",
                                (UCHAR*) pa07tracelevel,
                                sizeof(pa07tracelevel),
                                (UCHAR FAR *) "sql-db.ini");
        API_STRCPY(szModuleName, "");
        if (pa07tracefilename[1] != ':') {
            if (!API_STRCHR(pa07tracefilename, '\\')) {
                WORD wReturn;
                wReturn = _getdrive();
                _getdcwd(wReturn, szModuleName, sizeof(szModuleName));
            }
        }	   
        if (szModuleName[0] != '\0')
            if (szModuleName[API_STRLEN(szModuleName)-1] != '\\')
                API_STRCAT(szModuleName, "\\");
        API_STRCAT(szModuleName, pa07tracefilename);
        SetDlgItemText(hDlg,API_TRACELEVEL, pa07tracelevel);
        SetDlgItemText(hDlg,API_TRACEFILE, szModuleName);
        return (TRUE);
        break;
	}
	case WM_COMMAND: {
#ifdef WIN32
        WPARAM wParm = (WPARAM) LOWORD(wParam);
#else
        WPARAM wParm = wParam;
#endif
        switch (wParm) {
        case IDOK: {
            count = GetDlgItemText( hDlg,
                                    API_TRACELEVEL,
                                    pa07tracelevel,
                                    sizeof(pa07tracelevel));
            pa07tracelevel[count] = '\0';
            level = atoi(pa07tracelevel);
            count = GetDlgItemText( hDlg,
                                    API_TRACEFILE,
                                    pa07tracefilename,
                                    sizeof(pa07tracefilename));
            pa07tracefilename[count] = '\0';
            EndDialog(hDlg, TRUE);
            return (TRUE);
            break;
        }
        case IDCANCEL: {
            EndDialog(hDlg, FALSE);
            return (TRUE);
            break;
        }
        }
        break;
	}
    }
    return (FALSE);
} /* ProcDebug */


BOOL PASCAL EXPORT ProcAbout(hDlg, message, wParam, lParam)
HWND          hDlg;
unsigned int  message;
WPARAM        wParam;
LPARAM        lParam;
{
    switch (message) {
    case WM_INITDIALOG: {
        SetDlgItemText(hDlg, IDC_VERSION, API_DRIVER_VER);
        return FALSE;
    }
    case WM_COMMAND: {
#ifdef WIN32
        WPARAM wParm = (WPARAM) LOWORD(wParam);
#else
        WPARAM wParm = wParam;
#endif
        switch (wParm) {
	    case IDOK: {
            EndDialog(hDlg, wParm);
            return 0;
            break;
	    }
        }
    }
    }
    return FALSE;
} /* ProcAbout */

#ifndef _SETUP_ODBC_ONLY
UINT apduser(tpr05_String *szDSNStr,
             tpr05_String *useridStr,
             tpr05_String *passwdStr,
             UCHAR FAR * serverdb_ptr, SWORD serverdb_len,
             UCHAR FAR * servernode_ptr, SWORD servernode_len,
             HWND       hwnd1,
             const tsp77encoding *destEncoding,
             char *encrypt
             )

{
#define STRING_LEN ((API_USERID_MAX_LEN > API_PASSWD_MAX_LEN ? API_USERID_MAX_LEN : API_PASSWD_MAX_LEN) + 2)
    INT_PTR iRet;
    DLGPROC dlgprc;
#ifdef OLDTASK  
    HWND hwnd;
    HTASK hCurr;
#endif  
    unsigned int charOut;
    API_RETCODE retcode;
    profile_block useropt;
    profile_block *useropt_ptr = &useropt;
    SQLWCHAR szDSN[STRING_LEN];
    SQLWCHAR userid_ptr[STRING_LEN];
    SQLWCHAR passwd_ptr[STRING_LEN];

    SQLWCHAR serverdbW[STRING_LEN];
    SQLWCHAR servernodeW[2048];      /* for NI string PTS 1112202 */

    SQLSMALLINT szDSN_len, userid_len, passwd_len;

    static BOOL checkSSL = TRUE;
    static BOOL SSLavailable = FALSE;
    SQLCHAR connectbox[64];

    /* http://pts:1080/webpts?wptsdetail=yes&ErrorType=1&ErrorID=1134137 */
    if (checkSSL) {
      tsp00_ErrTextc  errtxt;
      checkSSL = FALSE;
      SSLavailable = SqlSSLAvailable (errtxt);
    }

    if (SSLavailable)
      strcpy (connectbox, "CONNECTBOXSSL");
    else
      strcpy (connectbox, "CONNECTBOX");

    szDSN_len = (SQLSMALLINT) szDSNStr->cbMaxLen / sizeof (SQLWCHAR);
    userid_len =(SQLSMALLINT) useridStr->cbMaxLen / sizeof (SQLWCHAR);
    passwd_len =(SQLSMALLINT) passwdStr->cbMaxLen / sizeof (SQLWCHAR);

    /* copy unicode into szDSN */
    if (szDSNStr->encodingType == sp77encodingAscii) {
      sp81ASCIItoUCS2 ((tsp00_Byte*) szDSN, sizeof (szDSN) / sizeof (SQLWCHAR) - 1,
                       sp77encodingUCS2Swapped == sp77nativeUnicodeEncoding (),
                       &charOut,
                       (tsp81_UCS2Char *) szDSNStr->rawString,
                       szDSNStr->cbLen);
      /* http://pts:1080/webpts?wptsdetail=yes&ErrorType=0&ErrorID=1123115 */
      szDSNStr->cbLen = charOut * sizeof (SQLWCHAR);
      API_MEMSET (&szDSN[charOut], 0, sizeof (SQLWCHAR));
    }
    else  {   /* UCS 2 */
      sp81UCS2strncpy (szDSN, szDSNStr->rawString, szDSNStr->cbLen / sizeof (SQLWCHAR));
      API_MEMSET (&szDSN[szDSNStr->cbLen / sizeof (SQLWCHAR)], 0, sizeof (SQLWCHAR));
    }

    if (useridStr->encodingType == sp77encodingAscii) {
      sp81ASCIItoUCS2 ((tsp00_Byte*) userid_ptr, sizeof (userid_ptr) / sizeof (SQLWCHAR) - 1,
                       sp77encodingUCS2Swapped == sp77nativeUnicodeEncoding (),
                       &charOut,
                       (tsp81_UCS2Char *) useridStr->rawString,
                       useridStr->cbLen);
      useridStr->cbLen = charOut * sizeof (SQLWCHAR);
      API_MEMSET (&userid_ptr[charOut], 0, sizeof (SQLWCHAR));
    }
    else  {   /* UCS 2 */
      sp81UCS2strncpy (userid_ptr, useridStr->rawString, useridStr->cbLen / sizeof (SQLWCHAR));
      API_MEMSET (&userid_ptr[useridStr->cbLen / sizeof (SQLWCHAR)], 0, sizeof (SQLWCHAR));
    }

    if (passwdStr->encodingType == sp77encodingAscii) {
      sp81ASCIItoUCS2 ((tsp00_Byte*) passwd_ptr, sizeof (passwd_ptr) / sizeof (SQLWCHAR) - 1,
                       sp77encodingUCS2Swapped == sp77nativeUnicodeEncoding (),
                       &charOut,
                       (tsp81_UCS2Char *) passwdStr->rawString,
                       passwdStr->cbLen);
      passwdStr->cbLen = charOut * sizeof (SQLWCHAR);
      API_MEMSET (&passwd_ptr[charOut], 0, sizeof (SQLWCHAR));
    }
    else  {   /* UCS 2 */
      sp81UCS2strncpy (passwd_ptr, passwdStr->rawString, passwdStr->cbLen / sizeof (SQLWCHAR));
      API_MEMSET (&passwd_ptr[passwdStr->cbLen / sizeof (SQLWCHAR)], 0, sizeof (SQLWCHAR));
    }

    sp81ASCIItoUCS2 ((tsp00_Byte*) serverdbW, sizeof (serverdbW) / sizeof (SQLWCHAR) - 1,
                     sp77encodingUCS2Swapped == sp77nativeUnicodeEncoding (),
                     &charOut,
                     (tsp81_UCS2Char *) serverdb_ptr,
                     serverdb_len);
    API_MEMSET (&serverdbW[charOut], 0, sizeof (SQLWCHAR));

    sp81ASCIItoUCS2 ((tsp00_Byte*) servernodeW, sizeof (servernodeW) / sizeof (SQLWCHAR) - 1,
                     sp77encodingUCS2Swapped == sp77nativeUnicodeEncoding (),
                     &charOut,
                     (tsp81_UCS2Char *) servernode_ptr,
                     servernode_len);
    API_MEMSET (&servernodeW[charOut], 0, sizeof (SQLWCHAR));



    API_TRACE(API_TR_ENTRY,"apduser",0);
    retcode = API_OK;
    useropt.dsn_ptr = szDSN;
    useropt.dsn_len = szDSN_len;
    useropt.userid_ptr = userid_ptr;
    useropt.userid_len = userid_len;
    useropt.passwd_ptr = passwd_ptr;
    useropt.passwd_len = passwd_len;
    useropt.serverdb_ptr = serverdbW;
    useropt.serverdb_len = sizeof (serverdbW) / sizeof (SQLWCHAR);  /* serverdb_len; */
    useropt.servernode_ptr = servernodeW;
    useropt.servernode_len = sizeof (servernodeW) / sizeof (SQLWCHAR);  /* servernode_len; */
    useropt.encrypt = *encrypt;
#ifdef OLDTASK  
    hCurr = GetCurrentTask();
    hwnd = pa07GetODBCTaskWindow(hCurr);
#endif  
#ifdef CTL3D_ALL    
    pa03InstallCtl3d(s_hModule);
#endif
    dlgprc = (DLGPROC) MakeProcInstance(ProcUser, s_hModule);

    

#ifdef _UNICODE_ODBC
    {
    SQLWCHAR connectboxw[64];
    unsigned int dummy;

    sp81ASCIItoUCS2 ((tsp81_UCS2Char*) connectboxw, sizeof(connectboxw),
                     sp77nativeUnicodeEncoding () == sp77encodingUCS2Swapped,
                     &dummy, (const tsp00_Byte*) connectbox,
                     strlen (connectbox));
    connectboxw[dummy] = 0;

    /* http://pts:1080/webpts?wptsdetail=yes&ErrorType=0&ErrorID=1116723 */
    iRet = DialogBoxParamW( s_hModule,
                            connectboxw,
                            hwnd1,
                            dlgprc,
                            (LPARAM) useropt_ptr);
    }
#else
    iRet = DialogBoxParam( s_hModule,
                           connectbox,
                           hwnd1,
                           dlgprc,
                           (LPARAM) useropt_ptr);
#endif
    FreeProcInstance((FARPROC) dlgprc);

    if (iRet == -1) {
        API_TRACE(API_TR_MSG," ERROR ====> DialogBox failed!",0);
        retcode = API_NOT_OK;
    }
    API_TRACE(API_TR_SWORD,"iRet",&((SWORD)iRet));
    if (retcode == API_OK) {
        switch (iRet) {
        case (TRUE): {
            retcode = API_OK;
            break;
        }
        case (FALSE):
            retcode = API_DATA_LOSS;
            break;
        }
    }

    pr05IfCom_String_ClearString (szDSNStr);
    pr05IfCom_String_strcatP (szDSNStr, szDSN, sp81UCS2strlen (szDSN) * sizeof (SQLWCHAR),
                              sp77nativeUnicodeEncoding ());

    pr05IfCom_String_ClearString (useridStr);
    pr05IfCom_String_strcatP (useridStr, userid_ptr, sp81UCS2strlen (userid_ptr) * sizeof (SQLWCHAR),
                              sp77nativeUnicodeEncoding ());

    pr05IfCom_String_ClearString (passwdStr);
    pr05IfCom_String_strcatP (passwdStr, passwd_ptr, sp81UCS2strlen (passwd_ptr) * sizeof (SQLWCHAR),
                              sp77nativeUnicodeEncoding ());

    sp81UCS2toASCII ((tsp00_Byte*) servernode_ptr, servernode_len - 1, &charOut,
                     servernodeW, sp81UCS2strlen (servernodeW),
                     sp77encodingUCS2Swapped == sp77nativeUnicodeEncoding ());
    servernode_ptr[charOut] = '\0';

    sp81UCS2toASCII ((tsp00_Byte*) serverdb_ptr, serverdb_len - 1, &charOut,
                     serverdbW, sp81UCS2strlen (serverdbW),
                     sp77encodingUCS2Swapped == sp77nativeUnicodeEncoding ());
    serverdb_ptr[charOut] = '\0';

    if (encrypt)
      *encrypt = (char) useropt.encrypt;

    API_TRACE(API_TR_STRING, "userid_ptr", userid_ptr);
    API_TRACE(API_TR_STRING, "passwd_ptr", "?");
    API_TRACE(API_TR_STRING, "serverdb_ptr", serverdb_ptr);
    API_TRACE(API_TR_STRING, "servernode_ptr", servernode_ptr);
    API_TRACE(API_TR_SWORD, "useropt.casesensitive", &useropt.casesensitive);
    API_TRACE(API_TR_EXIT, "apduser", 0);
    API_TRACE(API_TR_API_RETCODE, "retcode", &retcode);
    return(retcode);
} /* apduser */
#endif   /* _SETUP_ODBC_ONLY */


#ifdef OLDTASK
HWND pa07GetODBCTaskWindow(HTASK hCurr)
{
    HWND hwnd=0;
    SWORD i;
    API_TRACE(API_TR_ENTRY, "pa07GetODBCTaskWindow", 0);
    API_TRACE(API_TR_HWND, "hCurr", &hCurr);
    /* first search for an used task */
    for (i=0; i < MAX_TASK; i++) {
        if (pa07global[i].hTask == hCurr) {
            hwnd = pa07global[i].hWin;
            break;
        }	       
    }
    API_TRACE(API_TR_HWND,"hwnd", &hwnd);
    API_TRACE(API_TR_EXIT, "pa07GetODBCTaskWindow", 0);
    return (hwnd);
}
#endif
#endif

WORD FAR PCALL SendAHello(hwnd, msg, idEvent, dwtime)
    HWND hwnd;
UINT msg;
int idEvent;
DWORD dwtime;
{
    API_RETCODE api_retcode;
    API_HANDLE hnull = SQL_NULL_HSTMT;
    VOID FAR * null_ptr = NULL;
  
    API_TRACE(API_TR_ENTRY,"SendAHello",0);
    api_retcode = API_OK;
  
    API_TRACE(API_TR_EXIT,"SendAHello",0);
    API_TRACE(API_TR_API_RETCODE,"api_retcode",&api_retcode);
    return(api_retcode);
}


API_RETCODE apdncnnt( HDBC hdbc )
{
    API_RETCODE api_retcode;
    api_retcode = API_OK;
    API_TRACE(API_TR_ENTRY,"apdncnnt",0);
    API_TRACE(API_TR_HANDLE,"hdbc",&hdbc);
    /*  timerid = SetTimer((HWND)NULL, (UINT) hdbc, (UINT) 5000, lpSendAHello);*/
    /*  if ( timerid == 0) {*/
    /*     MessageBox(s_hModule, "Can't install timeout protector.", API_SERVER_NAME, MB_ICONEXCLAMATION | MB_OK);*/
    /*     api_retcode  = API_NOT_OK;*/
    /*  }  */
    /*    API_TRACE(API_TR_UWORD, "timerid",&timerid);*/
    API_TRACE(API_TR_EXIT, "apdncnnt",0);
    API_TRACE(API_TR_API_RETCODE,"api_retcode",&api_retcode);
    return(api_retcode);
}

UCHAR * apdnear(UCHAR FAR * far_pointer)
{

    static UCHAR near_buffer [ 100 ];

    API_STRCPY((UCHAR FAR *) near_buffer,far_pointer);

    return(near_buffer);
}

VOID apdentry ( name )
    UCHAR FAR * name;
{
    API_TRACE(API_TR_ENTRY, name, 0);
}

VOID apdexit ( name )
    UCHAR FAR * name;
{
    API_TRACE(API_TR_EXIT, name, 0);
}

VOID apdint2 ( s, n )
    UCHAR FAR * s;
SWORD n;
{
    API_TRACE(API_TR_SWORD,s, n);
}

VOID apdint4 ( s, n )
    UCHAR FAR * s;
SDWORD n;
{
    API_TRACE(API_TR_SDWORD,s,&n);
}

VOID apdtbuf ( ptr, pos, len )
    UCHAR FAR *ptr;
SDWORD pos;
SDWORD len;

{
    API_TRACE_BUF(ptr, pos, len);
}

VOID apdhex(string_ptr, str_len, hex_ptr, hex_len)
    UCHAR FAR *string_ptr;
SDWORD str_len;
UCHAR FAR *hex_ptr;
SDWORD hex_len;
{
    char err;
    
    s40gbyte( (UCHAR*) string_ptr , 1 , str_len ,
              (UCHAR*) hex_ptr , 1 , hex_len, (UCHAR*) &err);
    if (err != 0) {
        API_TRACE(API_TR_UCHAR,"apdhex err=",&err);   
        hex_ptr = NULL;
    }
    else
        hex_ptr[str_len+str_len]= '\0';
} 

static UCHAR FAR *API_TRACE_PREFIX = { (UCHAR*) "      "};

UCHAR FAR *pa07TracePrefix(pa07TraceLocals * lpTV) {
#ifdef ASYNCENABLED
    if (pa09ThreadCount > 1) {
        API_SPRINTF( (char*) lpTV->szTmpStr, "#%d%s",
                     lpTV->Id, API_TRACE_PREFIX);
        return(lpTV->szTmpStr);
    }
    else
        return(API_TRACE_PREFIX);
#else
    return(API_TRACE_PREFIX);
#endif
      
}

static UCHAR pa07stb[20];

UCHAR FAR *pa07Stack(VOID) {
    UDWORD i=0;
    pa07stb[0] = '\0';
#if defined (WIN32) && !defined (_WIN64)
#ifndef ALPHA
    __asm
        {
            mov i, esp;
        }
#endif
    API_SPRINTF(pa07stb, "sp:%#08lx", i);
#else
#if defined (WIN) && !defined (_WIN64)
    __asm
        {
            mov i, sp;
        }
    API_SPRINTF(pa07stb, "sp:%#08lx", i);
#endif
#endif
    return(pa07stb);
}


SWORD pa07IsTraceOn()
{
#ifdef WIN32
    UCHAR cpos   [ 20 ];
    GetPrivateProfileString((UCHAR*) API_TR_PROFENTRY,
                            (UCHAR*) API_SEC_TRACE,
                            (UCHAR*) "N",
                            (UCHAR*) cpos, sizeof(cpos),
                            (UCHAR*) "sql-db.ini");

    if (cpos[0] == 'N' || cpos[0] == 'n') 
        return(0);
    else
        return(1);
#else
    UCHAR  *parm_ptr;
    
    parm_ptr = (UCHAR*) getenv("APITRACE");
    if (parm_ptr == NULL || API_STRLEN(parm_ptr) == 0 )
        return(0);
    else
        return(1);
#endif
} /* pa07IsTraceOn */


SWORD pa07GetTraceLevel()
{
#ifdef WIN32
    if (pa07IsTraceOn()) 
        pa07maxlevel=apdoptt();
#else
    if (pa07IsTraceOn()) {
        UCHAR FAR *parm_ptr;
        parm_ptr = (UCHAR*) getenv("APITRLVL");
        if (parm_ptr != NULL ) {
            pa07maxlevel = (SWORD)atoi((char*) parm_ptr);
        }
    }
#endif
    else
        pa07maxlevel = 0;
    return(pa07maxlevel);
} /* pa07GetTraceLevel */


UCHAR FAR *pa07GetTraceFileName()
{
    if (pa07tracefilename[0] == '\0') {
        pa07SetTraceFileName(NULL);
    }
    return(pa07tracefilename);
} /* pa07GetTraceFileName */


void pa07SetTraceFileName(UCHAR FAR *ptr)
{      
    UCHAR FAR *deftracefile = (UCHAR*) "trace.log";
    if (!ptr)
        ptr = deftracefile;
    if(API_STRCMP(pa07tracefilename, ptr))
        api_trace_status=PA07_TRACEINIT;
    API_STRNCPY(pa07tracefilename, ptr, sizeof(pa07tracefilename)-1);
    if (api_trace_status==PA07_TRACEINIT)
        API_TRACE_INIT(PA07_TRACEINIT);
} /* pa07SetTraceFileName */


int pa07TraceSwitch(SWORD Level)
{
    if (Level > 0) {
        pa07maxlevel = Level;
        if (api_trace_status == PA07_TRACEINIT)
            API_TRACE_INIT(PA07_TRACEINIT);
        api_trace_status = PA07_TRACEON;
    }
    else 
        if (api_trace_status == PA07_TRACEON)
            api_trace_status = PA07_TRACEOFF;

    return api_trace_status;
} /* pa07TraceSwitch */


VOID pa07TraceOutPut(pa07TraceLocals *lpTV, UCHAR FAR *szBuffer)
{
    if (lpTV->level <= pa07maxlevel) {
        UCHAR FAR *p;
        long len;
#if defined(WIN32) && defined(AUTOFLUSH_TRACE)
        DWORD NumberOfBytesWritten;
        if (!lpTV->file_handle) {
            lpTV->file_handle = CreateFile( (UCHAR*) pa07GetTraceFileName(),
                                            GENERIC_WRITE,
                                            FILE_SHARE_WRITE,
                                            &pa07sa,
                                            OPEN_ALWAYS,
                                            FILE_ATTRIBUTE_NORMAL, NULL);
        };
#endif
        if (lpTV->file_handle == 0)
            API_EXIT_MSG(appexitmsg);
#if defined(WIN32) && defined(AUTOFLUSH_TRACE)
        SetFilePointer(lpTV->file_handle, 0, NULL, FILE_END);
#endif
        len = (long) API_STRLEN(szBuffer);
        for(p=szBuffer;len > 0;len-=256,p+=256) {
#if defined(WIN32) && defined(AUTOFLUSH_TRACE)
            WriteFile( lpTV->file_handle,
                       p,
                       (len > 256) ? 256 : len,
                       &NumberOfBytesWritten, NULL);
#else
            fprintf(lpTV->file_handle, "%*s", (len > 256) ? 256 : len, p);
#endif
            if (len > 256) {
#if defined(WIN32) && defined (AUTOFLUSH_TRACE)
                WriteFile( lpTV->file_handle,
                           CRLF,
                           sizeof(CRLF)-1,
                           &NumberOfBytesWritten, NULL);
#else
                fprintf(lpTV->file_handle, CRLF);
#endif
            }
        }
#if defined(WIN32) && defined(AUTOFLUSH_TRACE)
        CloseHandle(lpTV->file_handle);
        lpTV->file_handle = 0;
#else
        fflush(lpTV->file_handle);
#endif
    }
} /* pa07TraceOutPut */

#ifdef ASYNCENABLED
VOID pa07DeleteCriticalSection()
{
    if(pa07CriticalSection) {
        sqldestroymutex(&pa07CriticalSection);
        pa07CriticalSection = NULL;
    }
} /* pa07DeleteCriticalSection */

#endif

LPVOID pa07InitTraceValues()
{
    pa07TraceLocals  *lpV;
#ifdef ASYNCENABLED
    UCHAR ok;
    /* don't use apdallo beacause we cannnot trace at the moment */
    sqlallocat( sizeof(pa07TraceLocals), (UCHAR**) &lpV, &ok);
    if(!ok)
        lpV = NULL;
#else
    lpV = &pa07TraceValues;
#endif
    if (lpV) {
        API_MEMSET(lpV, 0, sizeof(pa07TraceLocals));
#ifdef ASYNCENABLED
        lpV->Id=pa09ThreadCount;
#endif
#if !defined(WIN32) || !defined(AUTOFLUSH_TRACE)
        lpV->file_handle=pa07file_handle;
#endif 
    }
    return(lpV);
} /* pa07InitTraceValues */

#ifdef WIN32
/* wrapper for Windows' GetDlgItemTextW. Under non unicode Windows (e.g. Win98)
   GetDlgItemTextW returns always 0, regardless of the content of the text field.
   In this case GetDlgItemText (Ansi) is called now, to get text under non
   unicode conditions. */
UINT pa07GetDlgItemTextW (HWND hDlg, int nIDDlgItem, LPWSTR lpString, int nMaxCount)
{
  UINT count;

  count = GetDlgItemTextW (hDlg, nIDDlgItem, lpString, nMaxCount);

  if (count == 0) {
      SQLCHAR     lpStrA[2048];  /* be generous due to NI connection strings */
      tsp00_Uint4 destBytesWritten, srcBytesParsed;

      count = GetDlgItemTextA (hDlg, nIDDlgItem, lpStrA, sizeof (lpStrA));

      if (count != 0)
        sp78convertString (sp77nativeUnicodeEncoding (),
                           lpString, nMaxCount,
                           &destBytesWritten,
                           TRUE,
                           sp77encodingAscii,
                           lpStrA, count,
                           &srcBytesParsed);
  }

  return (count);

}  /* pa07GetDlgItemTextW  */
/* wrapper for Windows' SetDlgItemTextW. Under non unicode Windows (e.g. Win98) */
BOOL pa07SetDlgItemTextW (HWND hDlg, int nIDDlgItem, LPCWSTR lpString)
{
  BOOL result = SetDlgItemTextW (hDlg, nIDDlgItem, lpString);

  if (result != TRUE) {
      SQLCHAR     lpStrA[2048];  /* be generous due to NI connection strings */
      tsp00_Uint4 strLen, i;
      tsp81_UCS2Char charW;

      /* change UCS2 string (that should consist only of 8-bit ASCII) to ASCII */
      strLen = sp81UCS2strlen ((const tsp81_UCS2Char*)lpString);
      for (i=0; i<strLen; i++) {
        charW.s = lpString[i];
        lpStrA[i] = (SQLCHAR) (charW.s < 256 ? charW.s : '?');
      }
      lpStrA[strLen] = '\0';

      result = SetDlgItemTextA (hDlg, nIDDlgItem, lpStrA);
  }

  return (result);
}  /* pa07SetDlgItemTextW */

#else


SWORD GetPrivateProfileString(UCHAR  *lpszSection, 
                              UCHAR  *lpszEntry, 
                              UCHAR  *lpszDefault,
                              UCHAR  *lpszReturnBuffer, 
                              SWORD   cbReturnBuffer, 
                              UCHAR  *lpszFileName)
{
    SWORD ret = FALSE;
    char  szLine[1024];
    tsp00_ErrTextc		errtxt;
    RTE_IniFileResult	errok;
    SAPDB_Int4 retv;

    API_TRACE(API_TR_ENTRY, "GetPrivateProfileString", 0);
    API_TRACE(API_TR_STRING, "lpszSection", lpszSection);
    API_TRACE(API_TR_STRING, "lpszEntry", lpszEntry);
    API_TRACE(API_TR_STRING, "lpszDefault", lpszDefault);
    API_TRACE(API_TR_PTR, "lpszReturnBuffer", &lpszReturnBuffer);
    API_TRACE(API_TR_SWORD, "cbReturnBuffer", &cbReturnBuffer);
    API_TRACE(API_TR_STRING, "lpszFileName", lpszFileName);

    /* call the SAPDB Runtime routines, first global than user repository */
    RTE_GetConfigString (SAPDB_ODBC_INI_FILE, (char *) lpszSection,
                         (char *) lpszEntry, szLine, sizeof(szLine), errtxt, &errok);
      
    switch (errok) {
    case SAPDB_INIFILE_RESULT_ERR_OPEN:
    case SAPDB_INIFILE_RESULT_ERR_LOCK:
    case SAPDB_INIFILE_RESULT_ERR_READ:
    case SAPDB_INIFILE_RESULT_NO_ENTRY:
      RTE_GetUserConfigString (NULL, SAPDB_ODBC_INI_FILE, (char *) lpszSection,
                               (char *) lpszEntry, szLine, sizeof(szLine), errtxt, &errok);
    default: {}
    }

    /* return the default value in case of error */
    if (errok != SAPDB_INIFILE_RESULT_OK)
      API_STRNCPY(lpszReturnBuffer, lpszDefault, cbReturnBuffer);
    else
      API_STRNCPY(lpszReturnBuffer, szLine, cbReturnBuffer);

    ret = (SWORD)API_STRLEN(lpszReturnBuffer);

    API_TRACE(API_TR_EXIT, "GetPrivateProfileString", 0);
    API_TRACE(API_TR_STRING, "lpszReturnBuffer", lpszReturnBuffer);
    API_TRACE(API_TR_SWORD, "ret", &ret);
    return(ret);
}

#define PA07CONVERT_TO_ASC(dest, src)              \
        sp78convertString (sp77encodingAscii,      \
                           dest, sizeof (dest),    \
                           &destBytesWritten,      \
                           TRUE,                   \
                           sp77encodingUCS2Native, \
                           src,                    \
                           sizeof(tsp81_UCS2Char) * sp81UCS2strlen ((tsp81_UCS2Char*) src),   \
                           &srcBytesParsed)

SWORD GetPrivateProfileStringW (SQLWCHAR  *lpszSection, 
                                SQLWCHAR  *lpszEntry, 
                                SQLWCHAR  *lpszDefault,
                                SQLWCHAR  *lpszReturnBuffer, 
                                SWORD      cbReturnBuffer, 
                                SQLWCHAR  *lpszFileName)
{
  SQLCHAR lSection[512], lEntry[100], lDefault[512];
  SQLCHAR lReturn[512], lFileName[512];
  tsp00_Uint4 destBytesWritten, srcBytesParsed;
  SWORD   ret;

  PA07CONVERT_TO_ASC (lSection, lpszSection);
  PA07CONVERT_TO_ASC (lEntry, lpszEntry);
  PA07CONVERT_TO_ASC (lDefault, lpszDefault);
  PA07CONVERT_TO_ASC (lFileName, lpszFileName);

  ret = GetPrivateProfileString (lSection, lEntry, lDefault,
                                 lReturn, sizeof (lReturn),
                                 lFileName);

  sp78convertString (sp77encodingUCS2Native,
                     lpszReturnBuffer, cbReturnBuffer,
                     &destBytesWritten,
                     TRUE,
                     sp77encodingAscii,
                     lReturn, API_STRLEN (lReturn),
                     &srcBytesParsed);

  return ret;
}

char *_strtime(char *tstr)
{
    time_t ltime;
    struct tm *ltm;
    time(&ltime);
    ltm = localtime(&ltime);
    strftime(tstr, 9, "%H:%M:%S", ltm);
    return(tstr);
}

#endif

/* END OF apdwin.c */
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
