.ad 8
.bm 8
.fm 4
.bt $Copyright by   Software AG, 1993$$Page %$
.tm 12
.hm 6
.hs 3
.tt 1 $NME$Project Distributed Database System$vos60c$
.tt 2 $$$
.tt 3 $R.Roedling$ message output $1997-05-14$
***********************************************************
.nf


    ========== licence begin LGPL
    Copyright (C) 2002 SAP AG

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

    This library 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
    Lesser General Public License for more details.

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

.fo
.nf
.sp
Module  : message_output
=========
.sp
Purpose :
.CM *-END-* purpose -------------------------------------
.sp
.cp 3
Define  :

.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :

.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :

.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  : R.Roedling
.sp
.cp 3
Created : 1992-10-25
.sp
.cp 3
Version : 1994-01-27
.sp
.cp 3
Release :  6.2 	 Date : 1997-05-14
.br
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
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
.oc _/1
.CM -lll-
Code    :
/*PRETTY*/


/*
 * INCLUDE FILES
 */
#include           <stdarg.h>

/*
 *  DEFINES
 */
#define MOD__  "VOS60C : "
#define MF__   MOD__"UNDEFINED"

#define MAX_HEADER_LEN                90

#define WRITE_TO_CONSOLE              0x01
#define WRITE_TO_DIAGFILE             0x02
#define WRITE_TO_EVENTLOG             0x04
#define WRITE_TO_APPL_DIAG            0x08
#define WRITE_TO_MSG_BOX              0x10
#define WRITE_TO_GUI_CONSOLE          0x20
#define WRITE_TO_ERR_DIAGFILE         0x40

                                      // --- Don't include 'WRITE_TO_MSG_BOX'
#define WRITE_TO_ALL                  WRITE_TO_CONSOLE      |  \
                                      WRITE_TO_DIAGFILE     |  \
                                      WRITE_TO_EVENTLOG     |  \
                                      WRITE_TO_APPL_DIAG    |  \
                                      WRITE_TO_GUI_CONSOLE  |  \
                                      WRITE_TO_ERR_DIAGFILE

// --- set default output devices
#if defined (WINCOMPO)
 #define DEFAULT_OUTPUT_DEVICE        WRITE_TO_MSG_BOX
#elif defined (USER)
 #define DEFAULT_OUTPUT_DEVICE        WRITE_TO_APPL_DIAG
#elif defined (SERVER) || defined (COMPO) || defined (KERNEL)
 #define DEFAULT_OUTPUT_DEVICE        WRITE_TO_CONSOLE
#else
 #define DEFAULT_OUTPUT_DEVICE        0
#endif



#define NO_HEADER                     0
#define BIG_HEADER                    1
#define BIG_USER_HEADER               2
#define SMALL_HEADER                  3
#define EVENT_LOG_HEADER              4
#define TIME_HEADER                   5

#define DF_RENAME_OLD_DIAGFILE        0x01
#define DF_APPEND_DIAG_OUTPUT         0x02


/*
 *  MACROS
 */
#if defined(_WIN32)
 #define  ENTER_CRIT_SEC()                                                    \
            if (!CritSecInitialized) { CritSecInitialized = TRUE;             \
              InitializeCriticalSection(&CritSec); }                          \
            EnterCriticalSection(&CritSec); CritSecCount++;

 #define  EXIT_CRIT_SEC()                                                     \
            if (CritSecCount) { CritSecCount--;                               \
              LeaveCriticalSection(&CritSec); }
#else
 #define  ENTER_CRIT_SEC()                                                    \
            DosEnterCritSec();

 #define  EXIT_CRIT_SEC()                                                     \
            DosExitCritSec();
#endif


/*
 *  LOCAL TYPE AND STRUCT DEFINITIONS
 */
typedef struct diag_file_record
  {
  HFILE     FileHandle;
  PATHNAME  szDiagFileName;
  PATHNAME  szPhysDiagFileName;
  BOOL      fStartOfWriteCycle;
  ULONG     ulBegOfWrtCycle;
  ULONG     ulWrtPos;
  ULONG     ulEndOfWrtCycle;
  } DIAG_FILE_REC;

typedef DIAG_FILE_REC  *PDIAG_FILE_REC;


/*
 * EXTERNAL VARIABLES
 */

/*
 *  EXPORTED VARIABLES
 */



/*
 * LOCAL VARIABLES
 */
#if defined(_WIN32)
static HANDLE           hEventSource        = NULL;
static PTOKEN_USER      pTU                 = NULL;
static CHAR             szEventLogTitle[80 + 1];
#endif

static BOOL             fUserDiagFileEnabled = FALSE;
static C40C             szUserDiagFileName;
static BOOL             fMessOutputDisabled  = FALSE;
static CRITICAL_SECTION CritSec;
static BOOL             CritSecInitialized   = FALSE;
static INT              CritSecCount         = 0;
static DIAG_FILE_REC    dfDiagFile           = { (HFILE)INVALID_HANDLE_VALUE,
                                                 "", "", FALSE,
                                                 0, 0, 0 };
static DIAG_FILE_REC    dfUtilDiagFile       = { (HFILE)INVALID_HANDLE_VALUE,
                                                 "", "", FALSE,
                                                 0, 0, 0 };
static HFILE            hfErrDiag            = (HFILE)INVALID_HANDLE_VALUE;
static PMSGFUNCTYPE     pGUIMessageFunc      = NULL;
static ULONG            ulOutput             = DEFAULT_OUTPUT_DEVICE;


/*
 * LOCAL FUNCTION PROTOTYPES
 */

#if defined(_WIN32)
 LONG sql60_write_event_log ( PSZ                   pszHeader,
                              PSZ                   pszMsg,
                              PSZ                   pszEventLogTitle,
                              LONG                  lMsgID,
                              HANDLE                hEventSource,
                              ULONG                 ulEventType );
#endif

LONG  sql60_get_cons_handle ( PHFILE                phfCon );
LONG  sql60_open_error_diag ( PSZ                   pszDiagFileName,
                              PSECURITY_ATTRIBUTES  pSA,
                              HFILE                 *FileHandle );
LONG  sql60_create_diag     ( PSZ                   pszHeaderInfo,
                              PSZ                   pszDiagFileName,
                              ULONG                 ulDiagOptions,
                              ULONG                 ulDiagSize,
                              PSECURITY_ATTRIBUTES  pSA,
                              PDIAG_FILE_REC        pDiagInfo );
LONG  sql60_write_con       ( PSZ                   pszHeader,
                              PSZ                   pszMsg );
LONG  sql60_write_GUI_con   ( PSZ                   pszHeader,
                              PSZ                   pszMsg );
LONG  sql60_write_mess_box  ( LONG                  lMsgID,
                              ULONG                 ulEventType,
                              PSZ                   pszMsg );
LONG  sql60_write_diag      ( PSZ                   pszHeader,
                              PSZ                   pszMsg,
                              ULONG                 ulMsgLen,
                              PDIAG_FILE_REC        pDiagInfo );
LONG  sql60_write_appl_diag ( PSZ                   pszHeader,
                              PSZ                   pszMsg );
LONG  sql60_init_diag_file  ( PSZ                   pszHeaderInfo,
                              ULONG                 ulDiagOptions,
                              ULONG                 ulDiagSize,
                              PDIAG_FILE_REC        pDiagInfo );
LONG  sql60_write_error_diag( PSZ                   pszHeader,
                              PSZ                   pszMsg,
                              HFILE                 FileHandle );
VOID  sql60_create_header   ( ULONG                 ulHeaderType,
                              LONG                  lMsgID,
                              ULONG                 ulEventType,
                              PSZ                   pszLabel,
                              PSZ                   pszOut );
VOID  sql60_deliver_msg     ( ULONG                 ulOutputRequest,
                              LONG                  lMsgID,
                              PSZ                   pszLabel,
                              PSZ                   pszMsg,
                              ULONG                 ulEventType );
LONG  sql60_emergency_write ( PSZ                   pszMsg,
                              LONG                  lMsgID,
                              PSZ                   pszLabel,
                              ULONG                 ulEventType );
LONG  sql60_user_diag_opt   ( BOOL                  *pfEnabled,
                              PSZ                   pszUserDiagName,
                              LONG                  lMxUserDiagName );


/*
 * ========================== GLOBAL FUNCTIONS ================================
 */

LONG sql60_open_event_log ( PSZ    pszEventLogTitle,
                            PSZ    pszEventLogSource )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_open_event_log"
  LONG         rc          = NO_ERROR;

  DBGIN;

  if ( ulOutput & WRITE_TO_EVENTLOG )
    {
    // --- already open!
    DBGOUT;
    return ( rc );
    }

  #if defined(_WIN32)
   #if defined (KERNEL) || defined (SERVER)
    // --- get user information
    rc = sql49c_get_token_information ( &pTU, NULL, NULL );

    if ( rc != NO_ERROR )
     pTU = NULL;
   #endif

   szEventLogTitle[sizeof(szEventLogTitle) - 1] = '\0';
   strncpy ( szEventLogTitle, pszEventLogTitle, sizeof(szEventLogTitle) - 4 );

   hEventSource = RegisterEventSource( NULL, pszEventLogSource );

   if ( hEventSource == NULL )
     {
     rc = GetLastError();
     sql60_msg_all ( ERR_CANT_OPEN_EVENT_LOG, rc );
     }
   else
     ulOutput |= WRITE_TO_EVENTLOG;

  #endif

  DBGOUT;
  return ( rc );
  }

/*------------------------------*/

VOID sql60_set_event_log_title ( PSZ pszEventLogTitle  )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_set_event_log_title"
  LONG         rc          = NO_ERROR;

  DBGIN;

   szEventLogTitle[sizeof(szEventLogTitle) - 1] = '\0';
   strncpy ( szEventLogTitle, pszEventLogTitle, sizeof(szEventLogTitle) - 4 );

  DBGOUT;
  return;
  }

/*------------------------------*/

LONG sql60_open_util_diag_file ( PSZ                  pszUtilDiagFileName,
                                 ULONG                ulDiagSize,
                                 PSECURITY_ATTRIBUTES pSA )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_open_util_diag_file"
  LONG                  rc    = NO_ERROR;
  ULONG                 ulDiagDevType;

  DBGIN;


  if ( pszUtilDiagFileName[0] == '\0' )
    {
    sql60_msg_all ( ERR_WRONG_DIAG_FILE_NAME, pszUtilDiagFileName );
    DBGOUT;
    return ( ERROR_INVALID_PARAMETER );
    }

  if ( ulDiagSize == 0 )
    {
    sql60_msg_all ( ERR_WRONG_DIAG_FILE_SIZE, pszUtilDiagFileName, ulDiagSize );
    DBGOUT;
    return ( ERROR_INVALID_PARAMETER );
    }


  // --- get device type  (Console, LPTx, COMx, PRN ...)
  ulDiagDevType = sql44c_get_dev_type_by_filename (pszUtilDiagFileName);

  switch (ulDiagDevType)
    {
    case DT_OTHER:
      ulDiagSize                       *= MAXPAGELENGTH;
      dfUtilDiagFile.fStartOfWriteCycle = FALSE;

      rc = sql60_create_diag ( TIME_HEADER_INFO_LINE,
                               pszUtilDiagFileName,
                               DF_APPEND_DIAG_OUTPUT,
                               ulDiagSize,
                               pSA,
                               &dfUtilDiagFile );

      if ( rc != NO_ERROR )
        {
        CLOSE_FILE (dfUtilDiagFile.FileHandle);
        dfUtilDiagFile.FileHandle            = (HFILE)INVALID_HANDLE_VALUE;
        dfUtilDiagFile.szPhysDiagFileName[0] = '\0';
        dfUtilDiagFile.szDiagFileName[0]     = '\0';
        dfUtilDiagFile.fStartOfWriteCycle    = FALSE;
        dfUtilDiagFile.ulBegOfWrtCycle       = 0;
        dfUtilDiagFile.ulWrtPos              = 0;
        dfUtilDiagFile.ulEndOfWrtCycle       = 0;
        }
      break;

    default:
      sql60_msg_all ( ERR_WRONG_DIAG_FILE_NAME, pszUtilDiagFileName );
      DBGOUT;
      rc = ERROR_INVALID_PARAMETER;
      break;
    }

  DBGOUT;
  return ( rc );
  }

/*------------------------------*/


LONG sql60_open_diag_file ( PSZ                  pszDiagFileName,
                            ULONG                ulDiagSize,
                            PSECURITY_ATTRIBUTES pSA )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_open_diag_file"
  LONG                  rc          = NO_ERROR;
  ULONG                 ulDiagDevType;

  DBGIN;

  if ( ulOutput & WRITE_TO_DIAGFILE )
    {
    // --- already open!
    DBGOUT;
    return ( NO_ERROR );
    }

  if ( pszDiagFileName[0] == '\0' )
    {
    sql60_msg_all ( ERR_WRONG_DIAG_FILE_NAME, pszDiagFileName );
    DBGOUT;
    return ( ERROR_INVALID_PARAMETER );
    }

  if ( ulDiagSize == 0 )
    {
    sql60_msg_all ( ERR_WRONG_DIAG_FILE_SIZE, pszDiagFileName, ulDiagSize );
    DBGOUT;
    return ( ERROR_INVALID_PARAMETER );
    }


  // --- get device type  (Console, LPTx, COMx, PRN ...)
  ulDiagDevType = sql44c_get_dev_type_by_filename (pszDiagFileName);

  switch (ulDiagDevType)
    {
    case DT_OTHER:
      ulDiagSize *= MAXPAGELENGTH;

      rc = sql60_create_diag ( BIG_HEADER_INFO_LINE,
                               pszDiagFileName,
                               DF_RENAME_OLD_DIAGFILE,
                               ulDiagSize,
                               pSA,
                               &dfDiagFile );

      if ( rc == NO_ERROR )
        ulOutput |= WRITE_TO_DIAGFILE;
      break;

    default:
      sql60_msg_all ( ERR_WRONG_DIAG_FILE_NAME, pszDiagFileName );
      DBGOUT;
      rc = ERROR_INVALID_PARAMETER;
      break;
    }

  DBGOUT;
  return ( rc );
  }

/*------------------------------*/

LONG sql60_open_error_diag_file ( PSZ                  pszDiagFileName,
                                  PSECURITY_ATTRIBUTES pSA )

  {
  #undef  MF__
  #define MF__ MOD__"sql60_open_error_diag_file"
  LONG                  rc    = NO_ERROR;
  ULONG                 ulDiagDevType;

  DBGIN;

  if ( ulOutput & WRITE_TO_ERR_DIAGFILE )
    {
    // --- already open!
    DBGOUT;
    return ( rc );
    }

  if ( pszDiagFileName[0] == '\0' )
    {
    sql60_msg_all ( ERR_WRONG_DIAG_FILE_NAME, pszDiagFileName );
    DBGOUT;
    return ( ERROR_INVALID_PARAMETER );
    }

  // --- get device type  (Console, LPTx, COMx, PRN ...)
  ulDiagDevType = sql44c_get_dev_type_by_filename (pszDiagFileName);

  switch (ulDiagDevType)
    {
    case DT_OTHER:
      rc = sql60_open_error_diag ( pszDiagFileName, pSA, &hfErrDiag );

      if ( rc == NO_ERROR )
        ulOutput |= WRITE_TO_ERR_DIAGFILE;

      break;

    default:
      sql60_msg_all ( ERR_WRONG_DIAG_FILE_NAME, pszDiagFileName );
      DBGOUT;
      rc = ERROR_INVALID_PARAMETER;
      break;
    }

  DBGOUT;
  return ( rc );
  }

/*------------------------------*/

VOID sql60_get_diag_filename ( PSZ *ppszPhysDiagFileName )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_get_diag_filename"

  DBGPAS;

  if ( dfDiagFile.szPhysDiagFileName[0] != '\0' )
    *ppszPhysDiagFileName = dfDiagFile.szPhysDiagFileName;
  else
    *ppszPhysDiagFileName = NULL;

  return;
  }

/*------------------------------*/

VOID sql60_enable_GUI_console ( PMSGFUNCTYPE pMessageFunc )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_open_GUI_console"

  DBGPAS;

  pGUIMessageFunc  = pMessageFunc;
  ulOutput        |= WRITE_TO_GUI_CONSOLE;

  return;
  }

/*------------------------------*/

VOID sql60_enable_default_device ( VOID )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_enable_default_device"

  DBGPAS;

  ulOutput |= DEFAULT_OUTPUT_DEVICE;

  return;
  }

/*------------------------------*/

VOID sql60_enable_message_box ( VOID )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_enable_message_box"

  DBGPAS;

  ulOutput |= WRITE_TO_MSG_BOX;

  return;
  }

/*------------------------------*/

VOID sql60_enable_console ( VOID )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_enable_console"

  DBGPAS;

  ulOutput |= WRITE_TO_CONSOLE;

  return;
  }

/*------------------------------*/

VOID sql60_enable_message_output ( VOID )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_enable_message_output"

  DBGPAS;

  fMessOutputDisabled = FALSE;

  return;
  }

/*------------------------------*/

VOID sql60_close_event_log ( VOID )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_close_event_log"

  DBGPAS;

  #if defined(_WIN32)
   if ( hEventSource != NULL )
     {
     if ( pTU != NULL )
       FREE_MEM (pTU);

     DeregisterEventSource( hEventSource );
     hEventSource  = NULL;
     ulOutput     &= ~WRITE_TO_EVENTLOG;
     }
  #endif
  }

/*------------------------------*/

VOID sql60_close_util_diag_file (VOID)
  {
  #undef  MF__
  #define MF__ MOD__"sql60_close_util_diag_file"

  DBGPAS;

  ENTER_CRIT_SEC();

  if ( dfUtilDiagFile.FileHandle != (HFILE) INVALID_HANDLE_VALUE )
    {
    CLOSE_FILE (dfUtilDiagFile.FileHandle);
    dfUtilDiagFile.FileHandle            = (HFILE)INVALID_HANDLE_VALUE;
    dfUtilDiagFile.szPhysDiagFileName[0] = '\0';
    dfUtilDiagFile.szDiagFileName[0]     = '\0';
    dfUtilDiagFile.fStartOfWriteCycle    = FALSE;
    dfUtilDiagFile.ulBegOfWrtCycle       = 0;
    dfUtilDiagFile.ulWrtPos              = 0;
    dfUtilDiagFile.ulEndOfWrtCycle       = 0;
    }

  EXIT_CRIT_SEC();

  return;
  }

/*------------------------------*/

VOID sql60_close_diag_file (VOID)
  {
  #undef  MF__
  #define MF__ MOD__"sql60_close_diag_file"
  HFILE       hfTmpDiag;

  DBGPAS;

  ENTER_CRIT_SEC();

  if ( dfDiagFile.FileHandle != (HFILE) INVALID_HANDLE_VALUE )
    {
    hfTmpDiag                        = dfDiagFile.FileHandle;
    ulOutput                        &= ~WRITE_TO_DIAGFILE;
    EXIT_CRIT_SEC();

    SLEEP(0);
    CLOSE_FILE (hfTmpDiag);
    dfDiagFile.FileHandle            = (HFILE)INVALID_HANDLE_VALUE;
    dfDiagFile.szPhysDiagFileName[0] = '\0';
    dfDiagFile.szDiagFileName[0]     = '\0';
    dfDiagFile.fStartOfWriteCycle    = FALSE;
    dfDiagFile.ulBegOfWrtCycle       = 0;
    dfDiagFile.ulWrtPos              = 0;
    dfDiagFile.ulEndOfWrtCycle       = 0;
    }
  else
    EXIT_CRIT_SEC();

  return;
  }

/*------------------------------*/

VOID sql60_close_error_diag_file (VOID)
  {
  #undef  MF__
  #define MF__ MOD__"sql60_close_error_diag_file"
  HFILE       hfTmpDiag;

  DBGPAS;

  ENTER_CRIT_SEC();

  if ( hfErrDiag != (HFILE) INVALID_HANDLE_VALUE )
    {
    hfTmpDiag                = dfDiagFile.FileHandle;
    ulOutput                &= ~WRITE_TO_ERR_DIAGFILE;
    EXIT_CRIT_SEC();

    SLEEP(0);
    CLOSE_FILE (hfTmpDiag);
    }
  else
    EXIT_CRIT_SEC();

  return;
  }

/*------------------------------*/

VOID sql60_disable_GUI_console( VOID )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_disable_GUI_console"

  DBGPAS;

  ulOutput &= ~WRITE_TO_GUI_CONSOLE;

  return;
  }

/*------------------------------*/

VOID sql60_disable_message_box ( VOID )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_disable_message_box"

  DBGPAS;

  ulOutput &= ~WRITE_TO_MSG_BOX;

  return;
  }

/*------------------------------*/

VOID sql60_disable_console ( VOID )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_disable_console"

  DBGPAS;

  ulOutput &= ~WRITE_TO_CONSOLE;

  return;
  }

/*------------------------------*/


VOID sql60_disable_default_device ( VOID )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_disable_default_device"

  DBGPAS;

  ulOutput &= ~DEFAULT_OUTPUT_DEVICE;

  return;
  }

/*------------------------------*/

VOID sql60_disable_message_output ( VOID )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_disable_message_output"

  DBGPAS;

  fMessOutputDisabled = TRUE;

  return;
  }

/*------------------------------*/

VOID _System  sql60_int_err_msg_prio7 ( PSZ  pszFormatStr, ... )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_int_err_msg_prio7"
  CHAR    String[MAX_MSG_LINE_LEN];
  va_list arg_ptr;

  DBGPAS;

  va_start(arg_ptr, pszFormatStr);
  vsprintf(String, pszFormatStr, arg_ptr);
  va_end(arg_ptr);

  sql60_msg_all ( IERR_INT_ERR_MSG_PRIO7, String );

  return;
  }

/*------------------------------*/

VOID _System sql60_msg_all ( LONG  lMsgID,
                             ULONG ulEventType,
                             PSZ   pszLabel,
                             PSZ   pszFormatStr, ...)
  {
  #undef  MF__
  #define MF__ MOD__"sql60_msg_all"
  CHAR        szMsg    [MAX_MSG_LINE_LEN];
  va_list     args ;

  DBGIN;

  ENTER_CRIT_SEC();
  va_start ( args, pszFormatStr);
  // --- Build Message Text
  vsprintf ( szMsg, pszFormatStr , args );

  va_end ( args );

  EXIT_CRIT_SEC();

  sql60_deliver_msg ( WRITE_TO_ALL, lMsgID, pszLabel,
                      szMsg, ulEventType );

  DBGOUT;
  return;
  }

/*------------------------------*/

VOID _System sql60_msg_box ( LONG  lMsgID,
                             ULONG ulEventType,
                             PSZ   pszLabel,
                             PSZ   pszFormatStr, ...)
  {
  #undef  MF__
  #define MF__ MOD__"sql60_msg_box"
  CHAR        szMsg    [MAX_MSG_LINE_LEN];
  va_list     args ;

  DBGIN;

  ENTER_CRIT_SEC();
  va_start ( args, pszFormatStr);
  // --- Build Message Text
  vsprintf ( szMsg, pszFormatStr , args );

  va_end ( args );

  EXIT_CRIT_SEC();

  sql60_deliver_msg ( WRITE_TO_MSG_BOX, lMsgID, pszLabel,
                      szMsg, ulEventType );

  DBGOUT;
  return;
  }

/*------------------------------*/

VOID _System sql60_msg_con_diag ( LONG  lMsgID,
                                  ULONG ulEventType,
                                  PSZ   pszLabel,
                                  PSZ   pszFormatStr, ...)
  {
  #undef  MF__
  #define MF__ MOD__"sql60_msg_con_diag"
  CHAR        szMsg    [MAX_MSG_LINE_LEN];
  va_list     args ;

  DBGIN;

  ENTER_CRIT_SEC();
  va_start ( args, pszFormatStr);
  // --- Build Message Text
  vsprintf ( szMsg, pszFormatStr , args );

  va_end ( args );

  EXIT_CRIT_SEC();

  sql60_deliver_msg ( WRITE_TO_CONSOLE     |
                      WRITE_TO_GUI_CONSOLE |
                      WRITE_TO_APPL_DIAG   |
                      WRITE_TO_DIAGFILE    |
                      WRITE_TO_ERR_DIAGFILE,
                      lMsgID, pszLabel,
                      szMsg, ulEventType );

  DBGOUT;
  return;
  }

/*------------------------------*/

VOID _System sql60_msg_diag ( LONG  lMsgID,
                              ULONG ulEventType,
                              PSZ   pszLabel,
                              PSZ   pszFormatStr, ...)
  {
  #undef  MF__
  #define MF__ MOD__"sql60_msg_diag"
  CHAR        szMsg    [MAX_MSG_LINE_LEN];
  va_list     args ;

  DBGIN;

  ENTER_CRIT_SEC();
  va_start ( args, pszFormatStr);
  // --- Build Message Text
  vsprintf ( szMsg, pszFormatStr , args );

  va_end ( args );

  EXIT_CRIT_SEC();


  sql60_deliver_msg ( WRITE_TO_APPL_DIAG   |
                      WRITE_TO_DIAGFILE    |
                      WRITE_TO_ERR_DIAGFILE,
                      lMsgID, pszLabel,
                      szMsg, ulEventType );

  DBGOUT;
  return;
  }

/*------------------------------*/

VOID _System sql60_msg_con ( LONG  lMsgID,
                             ULONG ulEventType,
                             PSZ   pszLabel,
                             PSZ   pszFormatStr, ...)
  {
  #undef  MF__
  #define MF__ MOD__"sql60_msg_con"
  CHAR        szMsg    [MAX_MSG_LINE_LEN];
  va_list     args ;

  DBGIN;

  ENTER_CRIT_SEC();
  va_start ( args, pszFormatStr);
  // --- Build Message Text
  vsprintf ( szMsg, pszFormatStr , args );

  va_end ( args );

  EXIT_CRIT_SEC();

  sql60_deliver_msg ( WRITE_TO_CONSOLE     |
                      WRITE_TO_GUI_CONSOLE,
                      lMsgID, pszLabel,
                      szMsg, ulEventType );

  DBGOUT;
  return;
  }

/*------------------------------*/

VOID _System sql60_msg_event_log ( LONG  lMsgID,
                                   ULONG ulEventType,
                                   PSZ   pszLabel,
                                   PSZ   pszFormatStr, ...)
  {
  #undef  MF__
  #define MF__ MOD__"sql60_msg_event_log"
  CHAR        szMsg    [MAX_MSG_LINE_LEN];
  va_list     args ;

  DBGIN;

  ENTER_CRIT_SEC();
  va_start ( args, pszFormatStr);
  // --- Build Message Text
  vsprintf ( szMsg, pszFormatStr , args );
  va_end ( args );

  EXIT_CRIT_SEC();

  sql60_deliver_msg ( WRITE_TO_EVENTLOG,
                      lMsgID, pszLabel,
                      szMsg, ulEventType );

  DBGOUT;
  return;
  }

/*------------------------------*/

VOID _System sql60_msg_con_event_log ( LONG  lMsgID,
                                       ULONG ulEventType,
                                       PSZ   pszLabel,
                                       PSZ   pszFormatStr, ...)
  {
  #undef  MF__
  #define MF__ MOD__"sql60_msg_con_event_log"
  CHAR        szMsg    [MAX_MSG_LINE_LEN];
  va_list     args ;

  DBGIN;

  ENTER_CRIT_SEC();
  va_start ( args, pszFormatStr);
  // --- Build Message Text
  vsprintf ( szMsg, pszFormatStr , args );
  va_end ( args );

  EXIT_CRIT_SEC();

  sql60_deliver_msg ( WRITE_TO_CONSOLE     |
                      WRITE_TO_GUI_CONSOLE |
                      WRITE_TO_EVENTLOG,
                      lMsgID, pszLabel,
                      szMsg, ulEventType );

  DBGOUT;
  return;
  }

/*------------------------------*/

VOID _System sql60_msg_prio_x ( ULONG ulPrio,
                                LONG  lMsgID,
                                PSZ   pszLabel,
                                PSZ   pszMsg,
                                ULONG ulEventType )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_msg_prio_x"
  ULONG        ulOutputRequest = 0;
  BOOL         fDiagFileAvail;

  DBGIN;

  fDiagFileAvail = ulOutput & (WRITE_TO_APPL_DIAG |
                               WRITE_TO_DIAGFILE  |
                               WRITE_TO_ERR_DIAGFILE);

  if ((ulPrio == 0) || (ulPrio == 6))
    ulOutputRequest |= WRITE_TO_EVENTLOG;

  if ((ulPrio == 0) || (ulPrio == 1) ||
      (ulPrio == 6)  || (ulPrio == 7) || !fDiagFileAvail )
    {
    ulOutputRequest |= WRITE_TO_CONSOLE     |
                       WRITE_TO_GUI_CONSOLE;
    }

  if ( fDiagFileAvail )
    {
    ulOutputRequest |= WRITE_TO_APPL_DIAG |
                       WRITE_TO_DIAGFILE  |
                       WRITE_TO_ERR_DIAGFILE;
    }

  sql60_deliver_msg ( ulOutputRequest, lMsgID, pszLabel,
                      pszMsg, ulEventType );

  DBGOUT;
  return;
  }

/*------------------------------*/

VOID sql60_strt_msg_wrt_cycle ( VOID )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_strt_msg_wrt_cycle"
  DBGIN;
  dfDiagFile.fStartOfWriteCycle = TRUE;
  DBGOUT;

  return;
  }

/*------------------------------*/

LONG sql60_write_to_util_diag ( PSZ             pszMsg,
                                ULONG           ulMsgLen )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_strt_msg_wrt_cycle"
  LONG        rc = NO_ERROR;
  CHAR        szHeader [MAX_HEADER_LEN];
  DBGIN;

  sql60_create_header ( TIME_HEADER,  0, 0, "", szHeader );

  rc = sql60_write_diag ( szHeader, pszMsg, ulMsgLen, &dfUtilDiagFile );

  if ( rc != NO_ERROR )
    {
    sql60_close_util_diag_file ();
    sql60_msg_all ( ERR_WRITING_DIAG_FILE, dfUtilDiagFile.szDiagFileName , rc );
    }


  DBGOUT;
  return ( rc );
  }

/*------------------------------*/

VOID sql60_reset_crit_section( VOID )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_reset_crit_section"

  DBGPAS;

  EXIT_CRIT_SEC();

  return;
  }

/*
 * ========================== LOCAL FUNCTIONS =================================
 */

static VOID  sql60_deliver_msg ( ULONG ulOutputRequest,
                                 LONG  lMsgID,
                                 PSZ   pszLabel,
                                 PSZ   pszMsg,
                                 ULONG ulEventType )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_deliver_msg"
  CHAR                  szHeader [MAX_HEADER_LEN];
  LONG                  rc                = NO_ERROR;
  BOOL                  fMessageDelivered = FALSE;
  DBGIN;

  if (( pszMsg[0] == '\0' ) || ( fMessOutputDisabled == TRUE ))
    {
    // --- there is nothing to do!
    DBGOUT;
    return;
    }

  #if defined(_WIN32)
   //
   // --- write to event log
   //
   if ((( ulOutput        & WRITE_TO_EVENTLOG ) &&
        ( ulOutputRequest & WRITE_TO_EVENTLOG )) ||
       (  ulOutput       == WRITE_TO_EVENTLOG ))
     {
     sql60_create_header ( EVENT_LOG_HEADER,  lMsgID,
                           ulEventType, pszLabel, szHeader );

     rc = sql60_write_event_log ( szHeader, pszMsg, szEventLogTitle, lMsgID,
                                  hEventSource, ulEventType );
     if ( rc != NO_ERROR )
       {
       ulOutput     &= ~WRITE_TO_EVENTLOG;
       DeregisterEventSource( hEventSource );
       hEventSource  = NULL;

       sql60_msg_all ( ERR_WRITING_EVENT_LOG, rc );
       DBG1 ((MF__, "Cannot write to the event log, rc = %d", rc ));
       }
     else
       fMessageDelivered = TRUE;
     }
  #endif

  //
  // --- write to message box
  //
  if ((( ulOutput        & WRITE_TO_MSG_BOX ) &&
       ( ulOutputRequest & WRITE_TO_MSG_BOX )) ||
      (  ulOutput       == WRITE_TO_MSG_BOX ))
    {
    if ( ulEventType != INFO_TYPE )
      sql60_write_mess_box ( lMsgID, ulEventType, pszMsg );

    fMessageDelivered = TRUE;
    }

  //
  // --- write to the console or GUI console
  //
  if ((( ulOutput        & WRITE_TO_CONSOLE ) &&
       ( ulOutputRequest & WRITE_TO_CONSOLE )) ||
      (  ulOutput       == WRITE_TO_CONSOLE ))
    {
    sql60_create_header ( SMALL_HEADER,  lMsgID,
                          ulEventType, pszLabel, szHeader );

    rc = sql60_write_con ( szHeader, pszMsg );

    if ( rc != NO_ERROR )
      {
      ulOutput &= ~WRITE_TO_CONSOLE;

      sql60_msg_all ( ERR_WRITING_CON_MSG, rc );
      DBG1 ((MF__, "Cannot write to console, rc = %d", rc ));
      }
    else
      fMessageDelivered = TRUE;
    }
  else if ((( ulOutput        & WRITE_TO_GUI_CONSOLE ) &&
            ( ulOutputRequest & WRITE_TO_GUI_CONSOLE )) ||
           (  ulOutput       == WRITE_TO_GUI_CONSOLE ))
    {
    sql60_create_header ( SMALL_HEADER,  lMsgID,
                          ulEventType, pszLabel, szHeader );

    rc = sql60_write_GUI_con ( szHeader, pszMsg );

    if ( rc != NO_ERROR )
      {
      ulOutput &= ~WRITE_TO_GUI_CONSOLE;

      sql60_msg_all ( ERR_WRITING_GUI_CON_MSG, rc );
      DBG1 ((MF__, "Cannot write to GUI console, rc = %d", rc ));
      }
    else
      fMessageDelivered = TRUE;
    }

  if (( ulOutput        &  WRITE_TO_ERR_DIAGFILE ) &&
      ( ulOutputRequest &  WRITE_TO_ERR_DIAGFILE ) &&
      ( ulEventType     != INFO_TYPE )             &&
      ( ulEventType     != WRN_TYPE ))
    {
    // ---  Create Message Header
    sql60_create_header ( BIG_HEADER,  lMsgID,
                          ulEventType, pszLabel, szHeader );

    rc = sql60_write_error_diag ( szHeader, pszMsg, hfErrDiag );

    if ( rc == NO_ERROR )
      fMessageDelivered = TRUE;
    }

  //
  // --- write to the diag file or application diag file
  //
  if ((( ulOutput        & WRITE_TO_DIAGFILE ) &&
       ( ulOutputRequest & WRITE_TO_DIAGFILE )) ||
      (  ulOutput       == WRITE_TO_DIAGFILE ))
    {
    // ---  Create Message Header

    sql60_create_header ( BIG_HEADER,  lMsgID,
                          ulEventType, pszLabel, szHeader );

    rc = sql60_write_diag ( szHeader, pszMsg, strlen(pszMsg), &dfDiagFile );

    if ( rc != NO_ERROR )
      {
      ulOutput &= ~WRITE_TO_DIAGFILE;

      sql60_close_diag_file ();
      sql60_msg_all ( ERR_WRITING_DIAG_FILE, dfDiagFile.szDiagFileName , rc );
      DBG1 ((MF__, "Cannot write to the diagnostic file, rc = %d", rc ));
      ABORT();
      }
    else
      fMessageDelivered = TRUE;
    }
  else if ((( ulOutput        & WRITE_TO_APPL_DIAG ) &&
            ( ulOutputRequest & WRITE_TO_APPL_DIAG )) ||
           (  ulOutput       == WRITE_TO_APPL_DIAG ))
    {
    // ---  Create Message Header
    sql60_create_header ( BIG_USER_HEADER,  lMsgID,
                          ulEventType, pszLabel, szHeader );

    rc = sql60_write_appl_diag ( szHeader, pszMsg );

    if ( rc != NO_ERROR )
      ulOutput &= ~WRITE_TO_APPL_DIAG;
    else
      fMessageDelivered = TRUE;
    }

  if ( fMessageDelivered == FALSE )
    rc = sql60_emergency_write ( pszMsg, lMsgID, pszLabel, ulEventType );

  DBGOUT;
  return;
  }

/*------------------------------*/

STATIC LONG sql60_get_cons_handle ( PHFILE phfCon )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_get_cons_handle"
  LONG         rc = NO_ERROR;

  DBGIN;

  #if defined(_WIN32)
   #if defined (KERNEL)
    *phfCon = (HFILE)INVALID_HANDLE_VALUE;
   #else
    *phfCon = (HFILE)GetStdHandle(STD_OUTPUT_HANDLE);

    if (*phfCon == (HFILE)INVALID_HANDLE_VALUE )
      {
      rc = GetLastError();
      DBG1 ((MF__, "Cannot access CONSOLE, rc = %d ", rc ));
      sql60_msg_all ( ERR_CANT_ACC_CONSOLE, rc );
      }
    else
      rc = NO_ERROR;
   #endif
  #else
   #if defined (KERNEL) && defined ( NEW_CONSOLE )
    *phfCon = (HFILE)INVALID_HANDLE_VALUE;
   #else
    *phfCon = STDOUT;
   #endif
  #endif

  DBGOUT;
  return ( rc );
  }

/*------------------------------*/

STATIC LONG sql60_create_diag ( PSZ                   pszHeaderInfo,
                                PSZ                   pszDiagFileName,
                                ULONG                 ulDiagOptions,
                                ULONG                 ulDiagSize,
                                PSECURITY_ATTRIBUTES  pSA,
                                PDIAG_FILE_REC        pDiagInfo )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_create_diag"
  LONG         rc;
  ULONG         ulFileType;
  PATHNAME      szPhysOldDiagFileName;
  PUCHAR        pucExt;
  #if !defined(_WIN32)
   ULONG        ulDeviceAttr;
   ULONG        Action;
   ULONG        ulOpenFlags;
   ULONG        ulOpenMode;
  #endif

  DBGIN;

  DBG3 ((MF__, "Open diagfile '%s' ", pDiagInfo->szPhysDiagFileName));

  // --- substitute logical path name parts
  sql44c_subst_log_parts ( pDiagInfo->szPhysDiagFileName, pszDiagFileName );
  strcpy ( pDiagInfo->szDiagFileName, pszDiagFileName );

  if ( DF_RENAME_OLD_DIAGFILE & ulDiagOptions )
    {
    strcpy ( szPhysOldDiagFileName, pDiagInfo->szPhysDiagFileName );
    pucExt = strrchr ( szPhysOldDiagFileName, '.' );

    if ( pucExt != NULL )
      *pucExt = '\0';

    strcat ( szPhysOldDiagFileName, ".old" );

    // --- delete old diagfile - ignore the return code
    // --- backup diagfile - ignore the return code
    DELETE_FILE( szPhysOldDiagFileName );
    MOVE_FILE  ( pDiagInfo->szPhysDiagFileName, szPhysOldDiagFileName );
    }

  #if defined(_WIN32)
   pDiagInfo->FileHandle = (HFILE)CreateFile( pDiagInfo->szPhysDiagFileName,
                                              GENERIC_READ | GENERIC_WRITE,
                                              FILE_SHARE_READ,
                                              pSA,
                                              OPEN_ALWAYS,
                                              FILE_ATTRIBUTE_NORMAL,
                                              NULL );

   if ( pDiagInfo->FileHandle == (HFILE)INVALID_HANDLE_VALUE )
     rc = GetLastError();
   else
     rc = NO_ERROR;
  #else
   ulOpenFlags = OPEN_ACTION_OPEN_IF_EXISTS |
                 OPEN_ACTION_CREATE_IF_NEW;
   ulOpenMode  = OPEN_FLAGS_FAIL_ON_ERROR   |     /* Open mode of the file */
                 OPEN_SHARE_DENYWRITE       |
                 OPEN_ACCESS_READWRITE;
   rc = DosOpen( pDiagInfo->szPhysDiagFileName,   /* File path name */
                 &pDiagInfo->FileHandle,          /* File handle */
                 &Action,                         /* Action taken */
                 0,                               /* File primary allocation */
                 FILE_NORMAL,                     /* File attribute */
                 ulOpenFlags,
                 ulOpenMode,
                 NOEABUF );                       /* No extended attributes */
  #endif

  if (rc == ERROR_SHARING_VIOLATION)
    {
    pDiagInfo->FileHandle = (HFILE)INVALID_HANDLE_VALUE;
    sql60_msg_all ( ERR_DIAG_FILE_IN_USE, pszDiagFileName, rc );
    DBG1 ((MF__, "File '%s' is already used by another process, rc = %u", pszDiagFileName, rc ));
    }
  else if ( rc == ERROR_ACCESS_DENIED )
    {
    pDiagInfo->FileHandle = (HFILE)INVALID_HANDLE_VALUE;
    sql60_msg_all ( ERR_ACCESS_DENIED_ON_XX, pszDiagFileName );
    DBG1 (( MF__, ERRMSG_VF_ACCESS_DENIED ));
    }
  else if (rc != NO_ERROR)
    {
    pDiagInfo->FileHandle = (HFILE)INVALID_HANDLE_VALUE;
    sql60_msg_all ( ERR_CANT_OPEN_DIAG_FILE, pszDiagFileName, rc );
    DBG1 ((MF__, "Cannot open diagnostic file: %s, rc = %d", pszDiagFileName, rc ));
    }
  else
    {
    #if defined(_WIN32)
     ulFileType = GetFileType( (HANDLE)pDiagInfo->FileHandle );

     if ( ulFileType != FILE_TYPE_DISK )
       {
       rc = ERROR_INVALID_PARAMETER;
       CLOSE_FILE( pDiagInfo->FileHandle );
       pDiagInfo->FileHandle = (HFILE)INVALID_HANDLE_VALUE;
       sql60_msg_all ( ERR_WRONG_DIAG_FILE_NAME, pszDiagFileName);
       DBG1 ((MF__, "Wrong diagnostic file name: '%s'", pszDiagFileName));
       }
    #else
     // --- query handle type
     rc = DosQueryHType(*FileHandle, &ulFileType, &ulDeviceAttr);

     ulFileType &= 7;     // -- extract the handle class

     if (rc != NO_ERROR)
       {
       rc = ERROR_INVALID_PARAMETER;
       CLOSE_FILE( pDiagInfo->FileHandle );
       pDiagInfo->FileHandle = (HFILE)INVALID_HANDLE_VALUE;
       sql60_msg_all ( ERR_QUERY_FILE_TYPE, pszDiagFileName, rc );
       DBG1 ((MF__, "Query file-type error for '%s'; rc = %d", pszDiagFileName, rc));
       }
     else if ( ulFileType != HANDTYPE_FILE )
       {
       rc = ERROR_INVALID_PARAMETER;
       CLOSE_FILE( pDiagInfo->FileHandle );
       pDiagInfo->FileHandle = (HFILE)INVALID_HANDLE_VALUE;
       sql60_msg_all ( ERR_WRONG_DIAG_FILE_NAME, pszDiagFileName);
       DBG1 ((MF__, "Wrong diagnostic file name: '%s'", pszDiagFileName));
       }
    #endif
    }

  if (rc == NO_ERROR)
    {
    rc = sql60_init_diag_file( pszHeaderInfo, ulDiagOptions,
                               ulDiagSize, pDiagInfo );
    }


  DBGOUT;
  return ( rc );
  }

/*------------------------------*/

STATIC LONG sql60_init_diag_file ( PSZ             pszHeaderInfo,
                                   ULONG           ulDiagOptions,
                                   ULONG           ulDiagSize,
                                   PDIAG_FILE_REC  pDiagInfo )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_init_diag_file"
  CHAR                        szBuff [(MAX_MSG_LINE_LEN + 2) * 10];
  PSZ                         pszBuff;
  PSZ                         pszFound;
  ULONG                       ulLocal;
  ULONG                       ulWritten;
  ULONG                       ulHeaderInfoSize;
  APIRET                      rc = NO_ERROR;
  INT                         i;
  LONG                        lPos;
  ULONG                       ulBytesRead;
  ULONG                       ulBytes;
  ULONG                       ulMovedBytes    = 0;
  BOOL                        fAppendPosFound = FALSE;
  #if defined(_WIN32)
   BY_HANDLE_FILE_INFORMATION InfoBuf;
  #endif

  DBGIN;

  pDiagInfo->ulEndOfWrtCycle = ulDiagSize -
                               sizeof (END_OF_DIAG_WRITE_CYCLE) - 1;


  if ( DF_APPEND_DIAG_OUTPUT & ulDiagOptions )
    {
    if ((GetFileInformationByHandle((HANDLE)pDiagInfo->FileHandle,&InfoBuf)) &&
        ( InfoBuf.nFileSizeLow == ulDiagSize ))
      {
      if ( pszHeaderInfo != NULL )
        pDiagInfo->ulBegOfWrtCycle = strlen(pszHeaderInfo);

      pDiagInfo->ulWrtPos           = 0;
      pDiagInfo->fStartOfWriteCycle = FALSE;
      ulBytes                       = sizeof(szBuff) - 1;
      pszBuff                       = szBuff;
      szBuff[sizeof(szBuff) - 1 ]   = '\0';

      do
        {
        rc = READ_FILE(pDiagInfo->FileHandle, pszBuff, ulBytes, &ulBytesRead);
        pszBuff[ulBytesRead] = '\0';

        if (( pszFound = strstr( szBuff, BEGIN_OF_DIAG_WRITE_CYCLE )) != NULL )
          {
          pDiagInfo->ulBegOfWrtCycle = pDiagInfo->ulWrtPos - ulMovedBytes +
                                       (ULONG)(pszFound - szBuff)        +
                                       sizeof (BEGIN_OF_DIAG_WRITE_CYCLE) - 1;
          }

        if (( pszFound = strstr( szBuff, CURR_DIAG_WRITE_POS )) != NULL )
          {
          fAppendPosFound      = TRUE;
          pDiagInfo->ulWrtPos += (ULONG)(pszFound - szBuff) - ulMovedBytes;
          }
        else
          {
          ulMovedBytes = min( MAX_MSG_LINE_LEN, ulBytesRead );
          memmove(szBuff, pszBuff + ulBytesRead - ulMovedBytes, ulMovedBytes );

          pDiagInfo->ulWrtPos += ulBytesRead;

          ulBytes = sizeof(szBuff) - 1 - ulMovedBytes;
          pszBuff = szBuff + ulMovedBytes;
          }
        }
      while (( rc              == NO_ERROR ) &&
             ( ulBytesRead     != 0 )        &&
             ( fAppendPosFound == FALSE ));

      if (( rc != NO_ERROR ) && ( rc != ERROR_HANDLE_EOF ))
        {
        CLOSE_FILE( pDiagInfo->FileHandle );
        pDiagInfo->FileHandle = (HFILE)INVALID_HANDLE_VALUE;

        sql60_msg_all ( ERR_READING_DIAG_FILE, pDiagInfo->szDiagFileName, rc );
        DBGOUT;
        return ( rc );
        }
      else
        SET_FILE_PTR( pDiagInfo->FileHandle, pDiagInfo->ulWrtPos,
                      FILE_BEGIN, &ulLocal, NULL );
      }
    }

  if ( fAppendPosFound == FALSE )
    {
    SET_FILE_PTR( pDiagInfo->FileHandle, 0, FILE_BEGIN, &ulLocal, NULL );

    if ( pszHeaderInfo != NULL )
      {
      ulHeaderInfoSize = strlen(pszHeaderInfo);
      rc = WRITE_FILE ( pDiagInfo->FileHandle, pszHeaderInfo,
                        ulHeaderInfoSize, &ulWritten );
      }
    else
      ulHeaderInfoSize = 0;

    ulDiagSize                -= ulHeaderInfoSize;
    pDiagInfo->ulBegOfWrtCycle = ulHeaderInfoSize;
    pDiagInfo->ulWrtPos        = ulHeaderInfoSize;

    // --- fill up the diagnostic file with blank characters
    if (rc == NO_ERROR)
      {
      memset (szBuff, ' ', sizeof(szBuff));

      for ( i = 1; i <= 10; i++)
        {
        lPos = (MAX_MSG_LINE_LEN + 2) * i;
        szBuff [ lPos - 1 ] = '\n';
        szBuff [ lPos - 2 ] = '\r';
        }

      while ((ulDiagSize > 0) && (rc == NO_ERROR))
        {
        rc = WRITE_FILE (pDiagInfo->FileHandle, szBuff, min(ulDiagSize, sizeof(szBuff)),
                        &ulWritten);
        ulDiagSize -= min(ulDiagSize, sizeof(szBuff));
        }
      }

    // --- write the info line of the write cycle end
    if (rc == NO_ERROR)
      {
      lPos = sizeof (END_OF_DIAG_WRITE_CYCLE) - 1;
      rc   = SET_FILE_PTR( pDiagInfo->FileHandle, -lPos,
                           FILE_END, &ulLocal, NULL );

      if ( rc == NO_ERROR )
        {
        rc = WRITE_FILE (pDiagInfo->FileHandle, END_OF_DIAG_WRITE_CYCLE,
                         sizeof(END_OF_DIAG_WRITE_CYCLE) - 1, &ulWritten);

        #if defined(_WIN32)
         SetEndOfFile( (HANDLE)pDiagInfo->FileHandle );
        #endif

        if (rc == NO_ERROR)
          rc = SET_FILE_PTR( pDiagInfo->FileHandle, pDiagInfo->ulBegOfWrtCycle,
                             FILE_BEGIN, &ulLocal, NULL );
        }
      }

    if ( rc != NO_ERROR )
      {
      CLOSE_FILE( pDiagInfo->FileHandle );
      pDiagInfo->FileHandle = (HFILE)INVALID_HANDLE_VALUE;

      sql60_msg_all ( ERR_WRITING_DIAG_FILE, pDiagInfo->szDiagFileName, rc );
      DBG1 ((MF__, "Cannot write to the diagnostic file, rc = %d ", rc ));
      }
    }

  DBGOUT;
  return ( rc );
  }

/*------------------------------*/

STATIC LONG sql60_open_error_diag ( PSZ                   pszDiagFileName,
                                    PSECURITY_ATTRIBUTES  pSA,
                                    HFILE                 *FileHandle )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_open_error_diag"
  LONG          rc;
  ULONG         ulFileType;
  ULONG         ulLocal;
  ULONG         ulWritten;
  CHAR          szOpenLine[MAX_MSG_LINE_LEN + 1];
  PATHNAME      szPhysDiagFileName;
  #if defined(_WIN32)
   SYSTEMTIME   DateTime;
  #else
   DATETIME     DateTime;
   ULONG        ulDeviceAttr;
   ULONG        Action;
   ULONG        ulOpenFlags;
   ULONG        ulOpenMode;
  #endif

  DBGIN;

  sql44c_subst_log_parts ( szPhysDiagFileName, pszDiagFileName );

  DBG3 ((MF__, "Open diagfile '%s' ", szPhysDiagFileName));

  #if defined(_WIN32)
   if ((*FileHandle = (HFILE)CreateFile( szPhysDiagFileName,
                                         GENERIC_READ      |
                                         GENERIC_WRITE,
                                         FILE_SHARE_READ,
                                         pSA,
                                         OPEN_ALWAYS,
                                         FILE_ATTRIBUTE_NORMAL,
                                         NULL )) == (HFILE)INVALID_HANDLE_VALUE)
     {
     rc = GetLastError();
     }
   else
     rc = NO_ERROR;
  #else
   ulOpenFlags = OPEN_ACTION_CREATE_IF_NEW  |     /* Open function type */
                 OPEN_ACTION_OPEN_IF_EXISTS;
   ulOpenMode  = OPEN_FLAGS_FAIL_ON_ERROR   |     /* Open mode of the file */
                 OPEN_SHARE_DENYWRITE       |
                 OPEN_ACCESS_READWRITE;
   rc = DosOpen( szPhysDiagFileName,              /* File path name */
                 FileHandle,                      /* File handle */
                 &Action,                         /* Action taken */
                 0,                               /* File primary allocation */
                 FILE_NORMAL,                     /* File attribute */
                 ulOpenFlags,
                 ulOpenMode,
                 NOEABUF );                       /* No extended attributes */
  #endif

  if (rc == ERROR_SHARING_VIOLATION)
    {
    *FileHandle = (HFILE)INVALID_HANDLE_VALUE;
    sql60_msg_all ( ERR_DIAG_FILE_IN_USE, pszDiagFileName, rc );
    DBG1 ((MF__, "File '%s' is already used by another process, rc = %u", pszDiagFileName, rc ));
    }
  else if ( rc == ERROR_ACCESS_DENIED )
    {
    *FileHandle = (HFILE)INVALID_HANDLE_VALUE;
    sql60_msg_all ( ERR_ACCESS_DENIED_ON_XX, pszDiagFileName );
    DBG1 (( MF__, ERRMSG_VF_ACCESS_DENIED ));
    }
  else if (rc != NO_ERROR)
    {
    *FileHandle = (HFILE)INVALID_HANDLE_VALUE;
    sql60_msg_all ( ERR_CANT_OPEN_DIAG_FILE, pszDiagFileName, rc );
    DBG1 ((MF__, "Cannot open diagnostic file: %s, rc = %d", pszDiagFileName, rc ));
    }
  else
    {
    #if defined(_WIN32)
     ulFileType = GetFileType( (HANDLE)*FileHandle );

     if ( ulFileType != FILE_TYPE_DISK )
       {
       rc = ERROR_INVALID_PARAMETER;
       CLOSE_FILE( *FileHandle );
       sql60_msg_all ( ERR_WRONG_DIAG_FILE_NAME, pszDiagFileName);
       DBG1 ((MF__, "Wrong diagnostic file name: '%s'", pszDiagFileName));
       }
    #else
     // --- query handle type
     rc = DosQueryHType(*FileHandle, &ulFileType, &ulDeviceAttr);

     ulFileType &= 7;     // -- extract the handle class

     if (rc != NO_ERROR)
       {
       rc = ERROR_INVALID_PARAMETER;
       CLOSE_FILE( *FileHandle );
       sql60_msg_all ( ERR_QUERY_FILE_TYPE, pszDiagFileName, rc );
       DBG1 ((MF__, "Query file-type error for '%s'; rc = %d", pszDiagFileName, rc));
       }
     else if ( ulFileType != HANDTYPE_FILE )
       {
       rc = ERROR_INVALID_PARAMETER;
       CLOSE_FILE( *FileHandle );
       sql60_msg_all ( ERR_WRONG_DIAG_FILE_NAME, pszDiagFileName);
       DBG1 ((MF__, "Wrong diagnostic file name: '%s'", pszDiagFileName));
       }
    #endif
    }

  if ( rc == NO_ERROR )
    {
    rc = SET_FILE_PTR( *FileHandle, 0, FILE_END, &ulLocal, NULL );

    if ( rc == NO_ERROR )
      {
      if ( ulLocal == 0 )
        {
        // --- write open message
        rc = WRITE_FILE ( *FileHandle, BIG_HEADER_INFO_LINE,
                           sizeof (BIG_HEADER_INFO_LINE) - 1, &ulWritten);
        }
      #if defined(_WIN32)
        GetLocalTime(&DateTime);
        wsprintf( szOpenLine,
                  ERR_FILE_OPEN_LINE,
                  DateTime.wMonth,
                  DateTime.wDay,
                  DateTime.wHour,
                  DateTime.wMinute,
                  DateTime.wSecond );

        DBG3((MF__, "Header = '%s'", pszOut));
      #else
        DosGetDateTime (&DateTime);

        sprintf ( szOpenLine,
                  ERR_FILE_OPEN_LINE,
                  DateTime.year % 100,
                  DateTime.month,
                  DateTime.day,
                  DateTime.hours,
                  DateTime.minutes,
                  DateTime.seconds );
      #endif

      // --- write header-info-line
      rc = WRITE_FILE ( *FileHandle, szOpenLine,
                          strlen(szOpenLine), &ulWritten);
      }

    if ( rc != NO_ERROR )
      {
      sql60_msg_all ( ERR_WRITING_ERROR_DIAG_FILE, rc );
      DBG1 ((MF__, "Cannot write to the error diagnostic file, rc = %d ", rc ));
      }
    }

  DBGOUT;
  return ( rc );
  }

/*------------------------------*/

#if defined(_WIN32)
 STATIC LONG sql60_write_event_log ( PSZ     pszHeader,
                                     PSZ     pszMsg,
                                     PSZ     pszEventLogTitle,
                                     LONG    lMsgID,
                                     HANDLE  hEventSource,
                                     ULONG   ulEventType )
   {
   #undef  MF__
   #define MF__ MOD__"sql60_write_event_log"
   APIRET    rc = NO_ERROR;
   LPTSTR    lpszStrings[ 3 ];
  #if defined(_WIN32)
   static BOOL          fLogFull  = FALSE;
  #endif

   DBGIN;

   lpszStrings[0] = pszEventLogTitle;
   lpszStrings[1] = pszHeader;
   lpszStrings[2] = pszMsg;

   switch ( ulEventType )
     {
     case  ERR_TYPE:  ulEventType = EVENTLOG_ERROR_TYPE;       break;
     case  WRN_TYPE:  ulEventType = EVENTLOG_WARNING_TYPE;     break;
     case  IERR_TYPE: ulEventType = EVENTLOG_ERROR_TYPE;       break;
     case  INFO_TYPE: ulEventType = EVENTLOG_INFORMATION_TYPE; break;
     default:         ulEventType = EVENTLOG_INFORMATION_TYPE; break;
     }

   if ( hEventSource != NULL )
     {
     if ( ReportEvent( hEventSource,
                       (WORD) ulEventType,
                       (WORD) ((lMsgID < 0) ? 1 : 0),
                       (lMsgID < 0) ? - lMsgID : lMsgID,
                       (pTU == NULL ) ? NULL : pTU->User.Sid,
                       3,
                       0,
                       lpszStrings,
                       NULL) == FALSE )
       {
       rc = GetLastError();
       }

     if ( rc == ERROR_LOG_FILE_FULL )
       {
       if ( fLogFull == FALSE )
         {
         fLogFull = TRUE;
         sql60_msg_all ( ERR_EVENT_LOG_FULL, rc );
         DBG1 ((MF__, "event log is full, rc = %d", rc ));
         }
       rc = NO_ERROR;
       }
     else if ( rc == NO_ERROR )
       fLogFull = FALSE;
     }

   DBGOUT;
   return ( rc );
   }
#endif

/*------------------------------*/

STATIC LONG sql60_write_con ( PSZ    pszHeader,
                              PSZ    pszMsg )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_write_con"
  APIRET               rc     = NO_ERROR;
  static HFILE         hfCon  = (HFILE)INVALID_HANDLE_VALUE;
  CHAR                 szTmpBuf  [MAX_MSG_LINE_LEN + 1];
  ULONG                ulWritten;

  DBGIN;

  strcpy  (szTmpBuf, pszHeader);
  strncat (szTmpBuf, pszMsg, MAX_MSG_LINE_LEN - 3);
  szTmpBuf[MAX_MSG_LINE_LEN - 2] = '\0';
  strcat (szTmpBuf, "\r\n");


  if ( hfCon == (HFILE)INVALID_HANDLE_VALUE )
    sql60_get_cons_handle ( &hfCon );

  if ( hfCon != (HFILE)INVALID_HANDLE_VALUE )
    {
    rc = WRITE_FILE ( hfCon, szTmpBuf, strlen(szTmpBuf), &ulWritten );

    if ( rc != NO_ERROR )
      hfCon = (HFILE)INVALID_HANDLE_VALUE;
    }

  DBGOUT;
  return ( rc );
  }

/*------------------------------*/

STATIC LONG sql60_write_GUI_con ( PSZ    pszHeader,
                                  PSZ    pszMsg )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_write_con"
  APIRET    rc = NO_ERROR;
  CHAR      szTmpBuf  [MAX_MSG_LINE_LEN + 1];

  DBGIN;

  strcpy  (szTmpBuf, pszHeader);
  strncat (szTmpBuf, pszMsg, MAX_MSG_LINE_LEN - 3);
  szTmpBuf[MAX_MSG_LINE_LEN - 2] = '\0';
  strcat (szTmpBuf, "\r\n");

  DBG3 ((MF__, szTmpBuf));

  rc = pGUIMessageFunc ( szTmpBuf );

  DBGOUT;
  return (rc);
  }

/*------------------------------*/

STATIC LONG sql60_write_mess_box ( LONG   lMsgID,
                                   ULONG  ulEventType,
                                   PSZ    pszMsg )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_write_mess_box"
  APIRET    rc = NO_ERROR;
  CHAR      szTmpBuf  [MAX_MSG_LINE_LEN + 1];
  #if defined(_WIN32)
   UINT     fuStyle;
  #else
   ULONG    fsStyle;
  #endif

  DBGIN;

  sprintf ( szTmpBuf, "\n%s  \n\nMessageID: %d\n", pszMsg, lMsgID );

  #if defined(_WIN32)
   switch ( ulEventType )
     {
     case WRN_TYPE :
       MessageBeep( MB_ICONEXCLAMATION );
       fuStyle = MB_OK | MB_ICONEXCLAMATION;
       break;
     case INFO_TYPE:
       MessageBeep( MB_ICONHAND );
       fuStyle = MB_OK | MB_ICONINFORMATION;
       break;
     default:
       MessageBeep( MB_ICONHAND );
       fuStyle = MB_OK | MB_ICONSTOP;
       break;
     }

   MessageBox( HWND_DESKTOP, szTmpBuf, (PSZ)"", fuStyle);

  #else
   switch ( ulEventType )
     {
     case WRN_TYPE :
       MessageBeep( MB_ICONEXCLAMATION );
       fuStyle = MB_OK | MB_ICONEXCLAMATION;
       break;
     case INFO_TYPE:
       MessageBeep( MB_ICONHAND );
       fuStyle = MB_OK | MB_ICONINFORMATION;
       break;
     default:
       MessageBeep( MB_ICONHAND );
       fuStyle = MB_OK | MB_ICONSTOP;
       break;
     }

   MessageBox( HWND_DESKTOP, szTmpBuf, (PSZ)"", fuStyle);
  #endif


  DBGOUT;
  return (rc);
  }

/*------------------------------*/

STATIC LONG sql60_write_diag ( PSZ             pszHeader,
                               PSZ             pszMsg,
                               ULONG           ulMsgLen,
                               PDIAG_FILE_REC  pDiagInfo )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_write_diag"
  #define  MSG_WPOS_INFO_SIZE    (sizeof ( "\r\n" ) - 1           + \
                                  sizeof ( CURR_DIAG_WRITE_POS)  - 1)

  CHAR             szStaticBuffer  [MAX_MSG_LINE_LEN    +
                                    MAX_HEADER_LEN      +
                                    MSG_WPOS_INFO_SIZE  + 1];
  PSZ              pszBuffer;
  PSZ              pszDynBuffer   = NULL;
  ULONG            ulOutputLen;
  ULONG            ulTmp;
  ULONG            ulLen;
  ULONG            ulHeaderLen;
  ULONG            ulWritten = 0;
  APIRET           rc        = NO_ERROR;

  DBGIN;

  if ( pszHeader )
    {
    ulHeaderLen = strlen(pszHeader);

    if ( ulHeaderLen > MAX_HEADER_LEN )
      {
      ulHeaderLen = MAX_HEADER_LEN;
      pszHeader[ulHeaderLen] = '\0';  // --- truncate header line
      }

    ulOutputLen = ulMsgLen + ulHeaderLen + MSG_WPOS_INFO_SIZE;
    }
  else
    {
    ulHeaderLen = 0;
    ulOutputLen = ulMsgLen + MSG_WPOS_INFO_SIZE;
    }

  if ( ulMsgLen > MAX_MSG_LINE_LEN )
    {
    rc = ALLOC_MEM ((PPVOID)&pszDynBuffer, ulOutputLen + 1);

    if( rc != NO_ERROR )
      {
      DBGOUT;
      return ( rc );
      }
    pszBuffer = pszDynBuffer;
    }
  else
    pszBuffer = szStaticBuffer;         // --- use static buffer

  // --- enter critical section
  ENTER_CRIT_SEC();

  if (pDiagInfo->FileHandle != (HFILE) INVALID_HANDLE_VALUE)
    {
    if ( pDiagInfo->fStartOfWriteCycle == TRUE )
      {
      pDiagInfo->fStartOfWriteCycle = FALSE;
      rc = WRITE_FILE (pDiagInfo->FileHandle, BEGIN_OF_DIAG_WRITE_CYCLE,
                       sizeof (BEGIN_OF_DIAG_WRITE_CYCLE) - 1, &ulWritten);

      pDiagInfo->ulWrtPos        += ulWritten;
      pDiagInfo->ulBegOfWrtCycle  = pDiagInfo->ulWrtPos;
      }

    // --- end of the write cycle area reached?
    if (( rc == NO_ERROR ) &&
        (pDiagInfo->ulWrtPos + ulOutputLen > pDiagInfo->ulEndOfWrtCycle))
      {
      ulLen = pDiagInfo->ulEndOfWrtCycle - pDiagInfo->ulWrtPos;
      memset (pszBuffer, ' ', ulLen );

      // --- overwrite old lines
      rc = WRITE_FILE (pDiagInfo->FileHandle, szStaticBuffer,
                       ulLen, &ulWritten);

      // --- set the filepointer to the begin of the write cycle area
      if (rc == NO_ERROR)
        rc = SET_FILE_PTR( pDiagInfo->FileHandle, pDiagInfo->ulBegOfWrtCycle,
                           FILE_BEGIN, &pDiagInfo->ulWrtPos, NULL );
      }

    // --- write the output line and the write-position-info-line
    if (rc == NO_ERROR)
      {
      // --- build the output line
      //
      if ( ulHeaderLen != 0 )
        {
        strcpy (pszBuffer, pszHeader );
        strncat (pszBuffer, pszMsg, ulMsgLen );
        pszBuffer[ulHeaderLen + ulMsgLen] = '\0';
        }
      else
        {
        strncpy (pszBuffer, pszMsg, ulMsgLen );
        pszBuffer[ulMsgLen] = '\0';
        }

      strcat  (pszBuffer, "\r\n"CURR_DIAG_WRITE_POS );

      rc = WRITE_FILE (pDiagInfo->FileHandle, pszBuffer, ulOutputLen,  &ulWritten);
      }
    // --- calculate the write position for the next incomming output line
    pDiagInfo->ulWrtPos += ulWritten - (sizeof(CURR_DIAG_WRITE_POS) - 1);

    // --- set the write position for the next incomming output line
    if (rc == NO_ERROR)
      rc = SET_FILE_PTR( pDiagInfo->FileHandle, pDiagInfo->ulWrtPos,
                         FILE_BEGIN, &ulTmp, NULL );

    #if defined(FLUSH_BUFFER)
     // --- Write Buffer to Disk
     if (rc == NO_ERROR)
       {
       #if defined(_WIN32)
        if (!FlushFileBuffers((HANDLE)pDiagInfo->FileHandle))
          rc = GetLastError();
       #else
        rc = DosResetBuffer(pDiagInfo->FileHandle);
       #endif
       }
    #endif
    }

  // --- exit critical section
  EXIT_CRIT_SEC();

  if ( pszDynBuffer != NULL )
    FREE_MEM ( (PVOID)pszDynBuffer );

  DBGOUT;
  return (rc);
  }

/*------------------------------*/

STATIC LONG sql60_write_error_diag ( PSZ    pszHeader,
                                     PSZ    pszMsg,
                                     HFILE  FileHandle )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_write_error_diag"
  APIRET               rc = NO_ERROR;
  CHAR                 szTmpBuf [MAX_MSG_LINE_LEN + 1];
  ULONG                ulWritten;

  DBGIN;

  strcpy  (szTmpBuf, pszHeader);
  strncat (szTmpBuf, pszMsg, MAX_MSG_LINE_LEN - 3);
  szTmpBuf[MAX_MSG_LINE_LEN - 2] = '\0';
  strcat (szTmpBuf, "\r\n");


  if ( FileHandle != (HFILE)INVALID_HANDLE_VALUE )
    rc = WRITE_FILE ( FileHandle, szTmpBuf, strlen(szTmpBuf), &ulWritten );

  DBGOUT;
  return ( rc );
  }

/*------------------------------*/

STATIC LONG sql60_write_appl_diag ( PSZ    pszHeader,
                                    PSZ    pszMsg )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_write_appl_diag"
  FILE         *fpUser;
  PATHNAME     szPhysUserDiagFileName;
  static BOOL  fInit = TRUE;
  PSZ          pszUserDiagFileEnabled;
  APIRET       rc = NO_ERROR;
  PSZ          pszDBRoot;

  DBGIN;

  if ( fInit == TRUE )
    {
    fInit = FALSE;

    //
    // --- write a diagfile?
    //
    rc = GETENV ( USERDIAG_ENV_VAR, &pszUserDiagFileEnabled );

    if (( rc == NO_ERROR )  && ( *pszUserDiagFileEnabled ))
      {
      if ( ! strcmp ( "YES", strupr ( pszUserDiagFileEnabled )))
        {
        fUserDiagFileEnabled = TRUE;

        if ( sql01c_get_dbroot ( &pszDBRoot ) )
          strcpy ( szUserDiagFileName,  FULL_USER_DIAGFILE_NAME );
        else
          strcpy ( szUserDiagFileName, USER_DIAGFILE_NAME );
        }
      else
        fUserDiagFileEnabled = FALSE;
      }
    else
      {
      #if defined ( _WIN32 )
       rc = sql60_user_diag_opt ( &fUserDiagFileEnabled,
                                  szUserDiagFileName,
                                  sizeof(szUserDiagFileName) - 1 );

       if ( rc != NO_ERROR )
         fUserDiagFileEnabled = FALSE;
      #else
       fUserDiagFileEnabled = FALSE;
      #endif
      }
    }

  if ( fUserDiagFileEnabled  == FALSE )
    return ( NO_ERROR );;

  // --- substitute logical path name parts
  sql44c_subst_log_parts ( szPhysUserDiagFileName, szUserDiagFileName );

  fpUser = fopen ( szPhysUserDiagFileName, "a");

  if ( fpUser == NULL )
    fpUser = fopen ( USER_DIAGFILE_NAME, "a");

  if ( fpUser != NULL )
    {
    fprintf ( fpUser, "%s%s\n", pszHeader, pszMsg );
    fclose ( fpUser );
    }

  DBGOUT;
  return ( NO_ERROR );
  }

/*------------------------------*/

STATIC LONG sql60_emergency_write ( PSZ    pszMsg,
                                    LONG   lMsgID,
                                    PSZ    pszLabel,
                                    ULONG  ulEventType )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_emergency_write"
  APIRET        rc        = NO_ERROR;
  static HANDLE hEventSrc = NULL;
  FILE          *fpUser;
  PATHNAME      szPhysUserDiagFileName;
  CHAR          szHeader [MAX_HEADER_LEN];

  DBGIN;

  #if defined(_WIN32)
   if ( hEventSrc == NULL )
     hEventSrc = RegisterEventSource( NULL, COMMON_DIAG_ID );

   if ( hEventSrc != NULL )
     {
     sql60_create_header ( EVENT_LOG_HEADER,  lMsgID,
                           ulEventType, pszLabel, szHeader );

     rc = sql60_write_event_log ( szHeader, pszMsg,
                                  LAST_CHANCE_INFO,
                                  lMsgID,
                                  hEventSrc,
                                  ulEventType );
     if ( rc != NO_ERROR )
       {
       DeregisterEventSource( hEventSrc );
       hEventSrc  = NULL;
       }
     else
       {
       DBGOUT;
       return ( NO_ERROR );
       }
     }
  #endif

  // --- write to appldiag first
  sql44c_subst_log_parts ( szPhysUserDiagFileName, FULL_USER_DIAGFILE_NAME );

  fpUser = fopen ( szPhysUserDiagFileName, "a");

  if ( fpUser == NULL )
    fpUser = fopen ( USER_DIAGFILE_NAME, "a");

  if ( fpUser != NULL )
    {
    // ---  Create Message Header
    sql60_create_header ( BIG_HEADER,  lMsgID,
                          ulEventType, pszLabel, szHeader );

    fprintf ( fpUser, "%s%s\n", szHeader, pszMsg );
    fclose ( fpUser );
    }


  DBGOUT;
  return ( NO_ERROR );
  }

/*------------------------------*/

STATIC VOID sql60_create_header ( ULONG   ulHeaderType,
                                  LONG    lMsgID,
                                  ULONG   ulEventType,
                                  PSZ     pszLabel,
                                  PSZ     pszOut )
  {
  #undef  MF__
  #define MF__ MOD__"sql60_create_header"
  #if defined(_WIN32)
    SYSTEMTIME   DateTime;
  #else
    DATETIME     DateTime;
  #endif
  CHAR          szTid[12];
  PSZ           pszTid;
  ULONG         ulTid  = 0;
  static CHAR   szPid[12];
  static PSZ    pszPid = szPid;
  static ULONG  ulPid  = 0;
  PSZ           pszType;
  PSZ           pszLongType;

  DBGIN;

  if ( ulPid == 0 )
    {
    GETPROCESSID(&ulPid);

    szPid[0] = '0';
    szPid[1] = 'x';
    _ultoa ( ulPid, szPid + 2, 16 );
    strupr ( szPid + 2 );

    if ( strlen(szPid) > 10 )
      pszPid = szPid + 2;
    else
      pszPid = szPid;
    }

  switch ( ulEventType )
    {
    case IERR_TYPE:
      //pszType     = "IER";
      pszType     = "ERR";
      pszLongType = IERR_LONG_DESCRIPTION;
      break;
    case ERR_TYPE:
      pszType     = "ERR";
      pszLongType = ERR_LONG_DESCRIPTION;
      break;
    case WRN_TYPE:
      pszType     = "WRN";
      pszLongType = WRN_LONG_DESCRIPTION;
      break;
    case INFO_TYPE:
      pszType     = "";
      pszLongType = INFO_LONG_DESCRIPTION;
      break;
    default:
      pszType     = "???";
      pszLongType = "???";
      break;
    }

  switch ( ulHeaderType )
    {
    case SMALL_HEADER:
      #if defined(_WIN32)
        wsprintf (pszOut, SMALL_HEADER_FORMAT_STR, lMsgID, pszLongType);
      #else
        ENTER_CRIT_SEC();
        sprintf (pszOut, SMALL_HEADER_FORMAT_STR, lMsgID, pszLongType);
        EXIT_CRIT_SEC();
      #endif
      break;

    case EVENT_LOG_HEADER:
      #if defined(_WIN32)

       ulTid = THREADID;
       szTid[0] = '0';
       szTid[1] = 'x';
       _ultoa ( ulTid, szTid + 2, 16 );
       strupr ( szTid + 2 );

       if ( strlen(szTid) > 10 )
         pszTid = szTid + 2;
       else
         pszTid = szTid;

       ENTER_CRIT_SEC();
       wsprintf( pszOut,
                 E_LOG_HEADER_FORMAT_STR,
                 pszLongType,
                 pszTid,
                 pszPid,
                 lMsgID );

       DBG3((MF__, "Header = '%s'", pszOut));
       EXIT_CRIT_SEC();
      #endif
     break;

    case BIG_HEADER:
      /*
        * Print Date and Time
        */
       ulTid = THREADID;
       szTid[0] = '0';
       szTid[1] = 'x';
       _ultoa ( ulTid, szTid + 2, 16 );
       strupr ( szTid + 2 );

       if ( strlen(szTid) > 10 )
         pszTid = szTid + 2;
       else
         pszTid = szTid;

      #if defined(_WIN32)
        GetLocalTime(&DateTime);
        ENTER_CRIT_SEC();
        wsprintf( pszOut,
                  BIG_HEADER_FORMAT_STR,
                  DateTime.wMonth,
                  DateTime.wDay,
                  DateTime.wHour,
                  DateTime.wMinute,
                  DateTime.wSecond,
                  pszTid,
                  pszType,
                  lMsgID,
                  pszLabel );

        DBG3((MF__, "Header = '%s'", pszOut));
        EXIT_CRIT_SEC();
      #else
        DosGetDateTime (&DateTime);

        ENTER_CRIT_SEC();
        sprintf ( pszOut,
                  BIG_HEADER_FORMAT_STR,
                  DateTime.year % 100,
                  DateTime.month,
                  DateTime.day,
                  DateTime.hours,
                  DateTime.minutes,
                  DateTime.seconds,
                  pszTid,
                  pszType,
                  lMsgID,
                  pszLabel );

        EXIT_CRIT_SEC();
      #endif
      break;

    case TIME_HEADER:
      /*
        * Print Date and Time
        */
      #if defined(_WIN32)
        GetLocalTime(&DateTime);
        ENTER_CRIT_SEC();
        wsprintf( pszOut,
                  TIME_HEADER_FORMAT_STR,
                  DateTime.wMonth,
                  DateTime.wDay,
                  DateTime.wHour,
                  DateTime.wMinute,
                  DateTime.wSecond );

        DBG3((MF__, "Header = '%s'", pszOut));
        EXIT_CRIT_SEC();
      #else
        DosGetDateTime (&DateTime);

        ENTER_CRIT_SEC();
        sprintf ( pszOut,
                  TIME_HEADER_FORMAT_STR,
                  DateTime.year % 100,
                  DateTime.month,
                  DateTime.day,
                  DateTime.hours,
                  DateTime.minutes,
                  DateTime.seconds );

        EXIT_CRIT_SEC();
      #endif
      break;

    case BIG_USER_HEADER:
      /*
       * Print Date and Time
       */
      #if defined(_WIN32)
        GetLocalTime(&DateTime);
        wsprintf( pszOut,
                  BIG_HEADER_FORMAT_STR,
                  DateTime.wMonth,
                  DateTime.wDay,
                  DateTime.wHour,
                  DateTime.wMinute,
                  DateTime.wSecond,
                  pszPid,
                  pszType,
                  lMsgID,
                  pszLabel );

        DBG3((MF__, "Header = '%s'", pszOut));
      #else
        DosGetDateTime (&DateTime);

        sprintf ( pszOut,
                  BIG_HEADER_FORMAT_STR,
                  DateTime.year % 100,
                  DateTime.month,
                  DateTime.day,
                  DateTime.hours,
                  DateTime.minutes,
                  DateTime.seconds,
                  pszPid,
                  pszType,
                  lMsgID,
                  pszLabel );
      #endif
      break;
    }

  DBGOUT;
  return;
  }

 /*------------------------------*/

STATIC LONG sql60_user_diag_opt ( BOOL *pfEnabled,
                                  PSZ   pszUserDiagName,
                                  LONG  lMxUserDiagName )
   {
   #undef  MF__
   #define MF__ MOD__"sql60_user_diag_opt"
   APIRET           rc = NO_ERROR;
   REG_ENTRY_REC    RegistryEntries[2];

   DBGPAS;

   RegistryEntries[0].pszValueName = REG_VN_DIAG_ENABLED;
   RegistryEntries[0].pValue       = pfEnabled;
   RegistryEntries[0].ulValueSize  = sizeof(DWORD);
   RegistryEntries[0].ulValueType  = REG_DWORD;

   RegistryEntries[1].pszValueName = REG_VN_DIAG_NAME;
   RegistryEntries[1].pValue       = pszUserDiagName;
   RegistryEntries[1].ulValueSize  = lMxUserDiagName + 1;
   RegistryEntries[1].ulValueType  = REG_SZ;

   rc = sql50_reg_get_applic_values ( NULL, HKEY_CURRENT_USER, "", 2,
                                      RegistryEntries );

   if (( rc != NO_ERROR ) && ( rc != ERROR_FILE_NOT_FOUND ))
     {
     MSGCD (( ERR_READ_USER_DIAG_OPT_VALS, rc ));
     return ( rc );
     }

   return ( rc );
   }




/*
 * =============================== END ========================================
 */
.CM *-END-* code ----------------------------------------
.SP 2
***********************************************************
.PA
