.ad
.bm 8
.fm 4
.bt $Copyright by   Software AG, 1993$$Page %$
.tm 12
.hm 6
.hs 3
.tt 1 $NME$Project Distributed Database System$vos33c$
.tt 2 $$$
.tt 3 $R.Roedling$ N A M E $1997-01-31$
***********************************************************
.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  :
=========
.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  :
.sp
.cp 3
Created :
.sp
.cp 3
Version :
.sp
.cp 3
Release :  6.2 	 Date : 1997-01-31
.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*/
/*
 * MODULE - local communication
 */

/*
 * INCLUDE FILES
 */

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


/*
 *  MACROS
 */


/*
 *  LOCAL TYPE AND STRUCT DEFINITIONS
 */


/*
 * EXTERNAL VARIABLES
 */


/*
 *  EXPORTED VARIABLES
 */


/*
 * LOCAL VARIABLES
 */

/*
 * LOCAL FUNCTION PROTOTYPES
 */

ULONG  sql33c_open_queue_mailslot  ( PSZ                   pszQueName,
                                     BOOL                  fConnectToXServer,
                                     PID                   *ppidServer,
                                     PHANDLE               phQueMailSlot,
                                     ERRORTEXT             pErrText );

ULONG  sql33c_write_queue_mailslot ( HANDLE                hQueMailSlot,
                                     PSZ                   pszClientObjName,
                                     ULONG                 ulReqType,
                                     ULONG                 ulServerRef,
                                     ULONG                 ulCSSize,
                                     ERRORTEXT             pErrText );

ULONG  sql33c_close_queue_mailslot ( HANDLE                hQueMailSlot,
                                     ERRORTEXT             pErrText );

ULONG  sql33c_create_client_sem    ( PSZ                   pszSemPath,
                                     PSZ                   pszClientObjName,
                                     PHEV                  phevClientSem,
                                     PSECURITY_ATTRIBUTES  pWorldSA,
                                     ERRORTEXT             pErrText );

ULONG  sql33c_wait_client_sem      ( HEV                   hevClientSem,
                                     ULONG                 ulTimeOut,
                                     ERRORTEXT             pErrText );

ULONG  sql33c_close_client_sem     ( HEV                   hevClientSem,
                                     ERRORTEXT             pErrText );

ULONG  sql33c_open_server_sem      ( PSZ                   pszSemPath,
                                     PSZ                   pszSemName,
                                     PHEV                  phevServerSem,
                                     ERRORTEXT             pErrText );

ULONG  sql33c_post_server_sem      ( HEV                   hevServerSem,
                                     ERRORTEXT             pErrText );

ULONG  sql33c_close_server_sem     ( HEV                   hevServerSem,
                                     ERRORTEXT             pErrText );

ULONG  sql33c_create_comm_seg      ( ULONG                 ulCSSize,
                                     PSZ                   pszClientObjName,
                                     PSECURITY_ATTRIBUTES  pWorldSA,
                                     PID                   pidServer,
                                     PHANDLE               phCS,
                                     PCOMM_SEG_HEADER_REC  *ppCSHeader,
                                     ERRORTEXT             pErrText );

ULONG  sql33c_lock_comm_seg        ( HANDLE                hCS,
                                     PSECURITY_ATTRIBUTES  pLockSA,
                                     ERRORTEXT             pErrText );

ULONG  sql33c_free_comm_seg        ( HANDLE                hCS,
                                     PCOMM_SEG_HEADER_REC  pCSHeader,
                                     ERRORTEXT             pErrText );

VOID   sql33c_init_comm_seg        ( PSHM_CONNECT_INFO_REC pShmConnInfo,
                                     PSZ                   pszClientObjName,
                                     PSZ                   pszSemPath,
                                     PSZ                   pszSemName,
                                     ERRORTEXT             pErrText );

ULONG sql33c_get_flag_comm_seg     ( PSZ                   pszFCSName,
                                     PHANDLE               phFCS,
                                     PFLAG_COMM_SEG        *ppFCS,
                                     ERRORTEXT             pErrText );

ULONG sql33c_free_flag_comm_seg    ( HANDLE                hFCS,
                                     PFLAG_COMM_SEG        pFCS,
                                     ERRORTEXT             pErrText );

VOID  sql33c_calculate_sizes       ( ULONG                 ulPacketCnt,
                                     ULONG                 ulMaxPacketSize,
                                     PULONG                pulPacketSize,
                                     PULONG                pulMaxDataLen,
                                     PULONG                pulCSSize );

ULONG sql33c_eval_conn_reply       ( PSHM_CONNECT_INFO_REC pShmConnInfo,
                                     PCONNECT_PARAM_REC    pConnParam,
                                     ERRORTEXT             pErrText );

ULONG sql33c_eval_xserv_conn_reply ( PSHM_CONNECT_INFO_REC pShmConnInfo,
                                     PCONNECT_PARAM_REC    pConnParam,
                                     ERRORTEXT             pErrText );

ULONG sql33c_connect_wait          ( HEV                   hevClientSem,
                                     ULONG                 ulServiceType,
                                     ULONG                 ulTimeOut,
                                     PCOMM_SEG_HEADER_REC  pCSHeader,
                                     ERRORTEXT             pErrText );

VOID  sql33c_connect_cleanup       ( PSHM_CONNECT_INFO_REC pShmConnInfo );
VOID  sql33c_init_conn_info        ( PSHM_CONNECT_INFO_REC pShmConnInfo,
                                     PCONNECT_PARAM_REC    pConnParam );

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

#if defined(SERVER)
 ULONG  sql33c_info_request ( PSZ                     pszServerDB,
                              ULONG                   ulServiceType,
                              ULONG                   ulPacketCnt,
                              PULONG                  pulPacketSize,
                              PULONG                  pulMaxDataLen,
                              PULONG                  pulMinReplySize,
                              ERRORTEXT               pErrText )
   {
   #undef  MF__
   #define MF__ MOD__"sql33c_info_request"
   ULONG                           ulCommState = SQLOK;
   HANDLE                          hFCS;
   PFLAG_COMM_SEG                  pFCS;
   SQL_DBNAMEC                     szServerDB;
   ULONG                           ulDummy = 0;
   DBGIN;

   // --- leave the orignal database name as it is!
   strcpy ( szServerDB,   pszServerDB );
   strupr ( szServerDB );

   ulCommState = sql33c_get_flag_comm_seg ( szServerDB, &hFCS,
                                            &pFCS, pErrText );
   if ( ulCommState != SQLOK )
     {
     // --- kernel might be inactive!
     DBGOUT;
     return ( ulCommState );
     }

   sql33c_calculate_sizes ( ulPacketCnt, pFCS->ulPacketSize,
                            pulPacketSize, pulMaxDataLen, &ulDummy );

   if ( ulServiceType == SQL_DISTRIBUTION )
     *pulMinReplySize = 0;
   else
     *pulMinReplySize = pFCS->ulMinReplySize;

   ulCommState = sql33c_free_flag_comm_seg ( hFCS, pFCS, pErrText );

   if ( ulCommState != SQLOK )
     {
     DBGOUT;
     return ( ulCommState );
     }

   if ( *pulPacketSize == 0 )
     {
     MSGD (( ERR_INVALID_PACKET_SIZE, *pulPacketSize ));
     sql46c_build_error_string ( pErrText, ERRMSG_INVALID_PACKET_SIZE, 0 );
     ulCommState = SQLNOTOK;
     }

   DBGOUT;
   return ( ulCommState );
   }
#endif

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

ULONG  sql33c_connect ( PCONNECT_PARAM_REC      pConnParam,
                        PSHM_CONNECT_INFO_REC   pShmConnInfo,
                        ERRORTEXT               pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql33c_connect"
  #if defined(_WIN32)
   IPC_BASE_OBJ_NAME              szClientObjName;
   PSZ                            pszClientObjName = szClientObjName;
  #else
   PSZ                            pszClientObjName = NULL;
  #endif
  PSZ                             pszClientSemPath;
  PSZ                             pszClientSemName;
  ULONG                           ulCommState;
  PID                             pidServer;

  DBGIN;

  // --- initialize the connect information record
  sql33c_init_conn_info ( pShmConnInfo, pConnParam );


  #if defined(_WIN32)
   sql41c_build_unique_obj_name ( pszClientObjName );
  #endif

  ulCommState = sql33c_get_flag_comm_seg ( pShmConnInfo->szServerDB,
                                           &pShmConnInfo->hFCS,
                                           &pShmConnInfo->pFCS,
                                           pErrText );

  if ( ulCommState != SQLOK ) // --- kernel/xserver might be inactive!
    {
    DBGOUT;
    return ( SQLNOTOK );
    }

  //
  // --- calculate sizes
  //
  sql33c_calculate_sizes ( pShmConnInfo->ulPacketCnt,
                           pShmConnInfo->pFCS->ulPacketSize,
                           &pShmConnInfo->ulPacketSize,
                           &pShmConnInfo->ulMaxDataLen,
                           &pShmConnInfo->ulCSSize );

  if ( pShmConnInfo->ulServiceType == SQL_DISTRIBUTION )
    pShmConnInfo->ulMinReplySize = 0;
  else
    pShmConnInfo->ulMinReplySize = pShmConnInfo->pFCS->ulMinReplySize;


  if ( pShmConnInfo->ulPacketSize == 0 )
    {
    MSGD (( ERR_INVALID_PACKET_SIZE, pShmConnInfo->ulPacketSize ));
    sql46c_build_error_string ( pErrText, ERRMSG_INVALID_PACKET_SIZE, 0 );
    sql33c_connect_cleanup  ( pShmConnInfo );
    DBGOUT;
    return ( SQLNOTOK );
    }


  ulCommState = sql33c_open_queue_mailslot ( pShmConnInfo->szServerDB,
                                             FALSE,
                                             &pidServer,
                                             &pShmConnInfo->hQueMailSlot,
                                             pErrText );

  if ( ulCommState != SQLOK )
    {
    sql33c_connect_cleanup  ( pShmConnInfo );
    DBGOUT;
    return ( SQLNOTOK );
    }

  #if defined (KERNEL)
   // --- we are using an external semaphore.
   pShmConnInfo->hevClientSem = pConnParam->hevClientSem;
   pszClientSemPath           = pConnParam->pszClientSemPath;
   pszClientSemName           = pConnParam->pszClientSemName;
  #else
   pszClientSemPath = SEM_USR;
   pszClientSemName = pszClientObjName;
   ulCommState      = sql33c_create_client_sem ( pszClientSemPath,
                                                 pszClientObjName,
                                                 &pShmConnInfo->hevClientSem,
                                                 pConnParam->pWorldSA,
                                                 pErrText );
   if ( ulCommState != SQLOK )
     {
     sql33c_connect_cleanup  ( pShmConnInfo );
     DBGOUT;
     return ( SQLNOTOK );
     }
  #endif

  ulCommState = sql33c_create_comm_seg ( pShmConnInfo->ulCSSize,
                                         pszClientObjName,
                                         pConnParam->pWorldSA,
                                         pidServer,
                                         &pShmConnInfo->hCS,
                                         &pShmConnInfo->pCSHeader,
                                         pErrText );
  if ( ulCommState != SQLOK )
    {
    sql33c_connect_cleanup  ( pShmConnInfo );
    DBGOUT;
    return ( SQLNOTOK );
    }


  sql33c_init_comm_seg( pShmConnInfo, pszClientObjName,
                        pszClientSemPath, pszClientSemName, pErrText );


  ulCommState = sql33c_write_queue_mailslot( pShmConnInfo->hQueMailSlot,
                                             pszClientObjName,
                                             SQL_RTE_CONNECT,
                                             0,
                                             pShmConnInfo->ulCSSize,
                                             pErrText );

  if ( ulCommState == SQLOK )
    {
    ulCommState = sql33c_connect_wait ( pShmConnInfo->hevClientSem,
                                        pShmConnInfo->ulServiceType,
                                        pConnParam->ulConnTimeout,
                                        pShmConnInfo->pCSHeader,
                                        pErrText );
    }

  // --- is everthing allright on the client side?
  if ( ulCommState == SQLOK )
    {
    // --- check if the server has reported an error!
    if (( pShmConnInfo->pCSHeader->ulServerFlag      == 1     ) &&
        ( pShmConnInfo->pCSHeader->ulServerCommState != SQLOK ))
      {
      // --- the server has reported an error!
      ulCommState = pShmConnInfo->pCSHeader->ulServerCommState;

      switch (  ulCommState )
        {
        case SQLTASKLIMIT :
          if ( pShmConnInfo->ulServiceType == SQL_UTILITY )
            {
            MSGD (( ERR_UTIL_ALREADY_CONN ));
            sql46c_build_error_string ( pErrText, ERRMSG_COM_UTIL_ALREADY_CONN, 0 );
            }
          else
            {
            MSGD (( ERR_TO_MANY_SESSIONS ));
            sql46c_build_error_string ( pErrText, ERRMSG_COM_TO_MANY_DB_SESSIONS, 0 );
            }
          break;

        case SQLSTART_REQUIRED:
          MSGD (( ERR_DATABASE_NOT_STARTED, pShmConnInfo->szServerDB ));
          sql46c_build_error_string ( pErrText,
                                      ERRMSG_COM_DATABASE_NOT_STARTED, 0 );
          break;

        default:
          MSGD (( ERR_CONN_REFUSED ))
          sql46c_build_error_string ( pErrText, ERRMSG_COM_CONN_REFUSED, 0 );
          break;
        }
      }
    else if (( pShmConnInfo->pCSHeader->ulServerFlag != 1 ) ||
             ( pShmConnInfo->pCSHeader->ulClientFlag != 2 ))
      {
      MSGD (( ERR_PROTOCOL_ERROR, "sql33c_connect" ));
      sql46c_build_error_string ( pErrText, ERRMSG_PROTOCOL_ERROR, 0 );

      ulCommState = SQLNOTOK;
      }
    }

  if ( ulCommState == SQLOK )
    {
    ulCommState = sql33c_lock_comm_seg ( pShmConnInfo->hCS,
                                         pConnParam->pLockSA,
                                         pErrText );
    }


  if ( ulCommState == SQLOK )
    {
    ulCommState = sql33c_open_server_sem ( pShmConnInfo->pCSHeader->szSemPath,
                                           pShmConnInfo->pCSHeader->szSemName,
                                           &pShmConnInfo->hevServerSem,
                                           pErrText );
    }


  if ( ulCommState == SQLOK )
    ulCommState = sql33c_eval_conn_reply( pShmConnInfo, pConnParam, pErrText );

  // --- is everthing allright?
  if ( ulCommState != SQLOK )
    {
    if ( pShmConnInfo->pCSHeader != NULL )
      {
      // --- signal to the server that we lost the connection!
      pShmConnInfo->pCSHeader->ulClientCommState  = SQLCRASH;
      pShmConnInfo->pCSHeader->ulClientFlag       = 1;
      pShmConnInfo->pCSHeader->ulServerFlag       = 2;
      }

    sql33c_connect_cleanup  ( pShmConnInfo );
    }
  else
    {
    // --- connected successfully!
    pShmConnInfo->pCSHeader->ulClientFlag = 0;
    pShmConnInfo->pCSHeader->ulServerFlag = 2;
    }

  DBGOUT;
  return ( ulCommState );
  }

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

#if defined(KERNEL)

 ULONG  sql33c_connect_xserver ( PCONNECT_PARAM_REC      pConnParam,
                                 PSHM_CONNECT_INFO_REC   pShmConnInfo,
                                 ERRORTEXT               pErrText )
   {
   #undef  MF__
   #define MF__ MOD__"sql33c_connect_xserver"
   #if defined(_WIN32)
    IPC_BASE_OBJ_NAME              szClientObjName;
    PSZ                            pszClientObjName = szClientObjName;
   #else
    PSZ                            pszClientObjName = NULL;
   #endif
   PSZ                             pszClientSemPath;
   PSZ                             pszClientSemName;
   ULONG                           ulCommState;
   PID                             pidServer;

   DBGIN;

   // --- initialize the connect information record
   sql33c_init_conn_info ( pShmConnInfo, pConnParam );

   #if defined(_WIN32)
    sql41c_build_unique_obj_name ( pszClientObjName );
   #endif

   //
   // --- calculate sizes
   //
   sql33c_calculate_sizes ( pShmConnInfo->ulPacketCnt,
                            pfcs->ulPacketSize,
                            &pShmConnInfo->ulPacketSize,
                            &pShmConnInfo->ulMaxDataLen,
                            &pShmConnInfo->ulCSSize );

   pShmConnInfo->ulMinReplySize = 0;

   if ( pShmConnInfo->ulPacketSize == 0 )
     {
     MSGD (( ERR_INVALID_PACKET_SIZE, pShmConnInfo->ulPacketSize ));
     sql46c_build_error_string ( pErrText, ERRMSG_INVALID_PACKET_SIZE, 0 );
     sql33c_connect_cleanup  ( pShmConnInfo );
     DBGOUT;
     return ( SQLNOTOK );
     }


   ulCommState = sql33c_open_queue_mailslot ( XSERVER_OBJ_NAME,
                                              TRUE,
                                              &pidServer,
                                              &pShmConnInfo->hQueMailSlot,
                                              pErrText );

   if ( ulCommState != SQLOK )
     {
     sql33c_connect_cleanup  ( pShmConnInfo );
     DBGOUT;
     return ( SQLNOTOK );
     }

   // --- we are using an external semaphore.
   pShmConnInfo->hevClientSem = pConnParam->hevClientSem;
   pszClientSemPath           = pConnParam->pszClientSemPath;
   pszClientSemName           = pConnParam->pszClientSemName;

   ulCommState = sql33c_create_comm_seg ( pShmConnInfo->ulCSSize,
                                         pszClientObjName,
                                         pConnParam->pWorldSA,
                                         pidServer,
                                         &pShmConnInfo->hCS,
                                         &pShmConnInfo->pCSHeader,
                                         pErrText );
   if ( ulCommState != SQLOK )
     {
     sql33c_connect_cleanup  ( pShmConnInfo );
     DBGOUT;
     return ( SQLNOTOK );
     }


   sql33c_init_comm_seg( pShmConnInfo, pszClientObjName,
                         pszClientSemPath, pszClientSemName, pErrText );


   ulCommState = sql33c_write_queue_mailslot( pShmConnInfo->hQueMailSlot,
                                             pszClientObjName,
                                             SQL_RTE_CONNECT,
                                             0,
                                             pShmConnInfo->ulCSSize,
                                             pErrText );

   if ( ulCommState == SQLOK )
     {
     ulCommState = sql33c_connect_wait ( pShmConnInfo->hevClientSem,
                                         pShmConnInfo->ulServiceType,
                                         pConnParam->ulConnTimeout,
                                         pShmConnInfo->pCSHeader,
                                         pErrText );
     }

   // --- is everthing allright on the client side?
   if ( ulCommState == SQLOK )
     {
     // --- check if the server has reported an error!
     if (( pShmConnInfo->pCSHeader->ulServerFlag      == 1     ) &&
         ( pShmConnInfo->pCSHeader->ulServerCommState != SQLOK ))
       {
       // --- the server has reported an error!
       ulCommState = pShmConnInfo->pCSHeader->ulServerCommState;

       switch (  ulCommState )
         {
         case SQLTASKLIMIT :
           if ( pShmConnInfo->ulServiceType == SQL_UTILITY )
             {
             MSGD (( ERR_UTIL_ALREADY_CONN ));
             sql46c_build_error_string ( pErrText, ERRMSG_COM_UTIL_ALREADY_CONN, 0 );
             }
           else
             {
             MSGD (( ERR_TO_MANY_SESSIONS ));
             sql46c_build_error_string ( pErrText, ERRMSG_COM_TO_MANY_DB_SESSIONS, 0 );
             }
           break;

         case SQLSTART_REQUIRED:
           MSGD (( ERR_COM_SERVER_OR_DB_NOT_ACC ));
           sql46c_build_error_string ( pErrText, ERRMSG_COM_SERVER_OR_DB_NOT_ACC, 0 );
           break;

         default:
           MSGD (( ERR_CONN_REFUSED ))
           sql46c_build_error_string ( pErrText, ERRMSG_COM_CONN_REFUSED, 0 );
           break;
         }
       }
     else if (( pShmConnInfo->pCSHeader->ulServerFlag != 1 ) ||
              ( pShmConnInfo->pCSHeader->ulClientFlag != 2 ))
       {
       MSGD (( ERR_PROTOCOL_ERROR, "sql33c_connect_xserver" ));
       sql46c_build_error_string ( pErrText, ERRMSG_PROTOCOL_ERROR, 0 );

       ulCommState = SQLNOTOK;
       }
     }

   if ( ulCommState == SQLOK )
     {
     ulCommState = sql33c_lock_comm_seg ( pShmConnInfo->hCS,
                                          pConnParam->pLockSA,
                                          pErrText );
     }


   if ( ulCommState == SQLOK )
     {
     ulCommState = sql33c_open_server_sem ( pShmConnInfo->pCSHeader->szSemPath,
                                            pShmConnInfo->pCSHeader->szSemName,
                                            &pShmConnInfo->hevServerSem,
                                            pErrText );
     }


   if ( ulCommState == SQLOK )
     {
     ulCommState = sql33c_eval_xserv_conn_reply ( pShmConnInfo, pConnParam,
                                                 pErrText);
     }

   // --- is everthing allright?
   if ( ulCommState != SQLOK )
     {
     if ( pShmConnInfo->pCSHeader != NULL )
       {
       // --- signal to the server that we lost the connection!
       pShmConnInfo->pCSHeader->ulClientCommState  = SQLCRASH;
       pShmConnInfo->pCSHeader->ulClientFlag       = 1;
       pShmConnInfo->pCSHeader->ulServerFlag       = 2;
       }

     sql33c_connect_cleanup  ( pShmConnInfo );
     }
   else
     {
     // --- connected successfully!
     pShmConnInfo->pCSHeader->ulClientFlag = 0;
     pShmConnInfo->pCSHeader->ulServerFlag = 2;
     }

   DBGOUT;
   return ( ulCommState );
   }

#endif

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

ULONG  sql33c_request ( PSHM_CONNECT_INFO_REC   pShmConnInfo,
                        ULONG                   ulCmdPacket,
                        ULONG                   ulCmdDataLen,
                        ERRORTEXT               pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql33c_request"
  APIRET                          rc          = NO_ERROR;
  PCOMM_SEG_HEADER_REC            pCSHeader;
  PCOMM_PACKET_REC                pCommPacket = NULL;
  ULONG                           ulCommState;
  ULONG                           ulMessClass;

  DBGIN;

  pCSHeader                     = pShmConnInfo->pCSHeader;
  pCommPacket                   = pShmConnInfo->pCommPacketList[ulCmdPacket];
  pShmConnInfo->ulCurrentPacket = ulCmdPacket;
  pShmConnInfo->ulCmdDataLen    = ulCmdDataLen;

  DBG3 (( MF__, "ulServerCommState: %d", pCSHeader->ulServerCommState  ));
  DBG3 (( MF__, "ulClientCommState: %d", pCSHeader->ulClientCommState  ));
  DBG3 (( MF__, "ulServerFlag     : %d", pCSHeader->ulServerFlag ));
  DBG3 (( MF__, "ulClientFlag     : %d", pCSHeader->ulClientFlag ));

  // --- ClientFlag must be 0
  #if !defined (KERNEL)
   if ( pCSHeader->ulClientFlag != 0 )
     {
     MSGD (( ERR_UNBAL_REQUEST_REPLY ));
     sql46c_build_error_string ( pErrText, ERRMSG_COM_UNBALANCED_REQUEST_REPLY,
                                0 );
     DBGOUT;
     return ( SQLNOTOK );
     }
  #endif

  if (( pCSHeader->ulServerRef       != pShmConnInfo->ulServerRef ) ||
      ( pCSHeader->ulServerCommState != SQLOK )                     ||
      ( pCSHeader->ulServerFlag      == 1 ))
    {
    if ( pCSHeader->ulServerCommState == SQLTIMEOUT )
      {
      MSGD (( INFO_COM_TIMEOUT ));
      sql46c_build_error_string ( pErrText, ERRMSG_COM_TIMEOUT, 0 );
      }
    else
      sql46c_build_error_string ( pErrText, ERRMSG_COM_CONN_BROKEN, 0 );

    if ( pCSHeader->ulServerCommState != SQLOK )
      {
      DBGOUT;
      return ( pCSHeader->ulServerCommState );
      }
    else
      {
      DBGOUT;
      return ( SQLNOTOK );
      }
    }

  //
  // --- Setup the RTE header.
  //
  if ( pShmConnInfo->ulServiceType == SQL_DISTRIBUTION )
    ulMessClass = RSQL_KERN_DATA_REQUEST;
  else
    ulMessClass = RSQL_USER_DATA_REQUEST;

  pCommPacket->RTEHeader.ActSendLen      = (INT4)ulCmdDataLen +
                                           RTE_HEADER_SIZE;
  pCommPacket->RTEHeader.ProtocolID      = RSQL_RTE_PROT_UNDEF;
  pCommPacket->RTEHeader.MessClass       = (INT1)ulMessClass;
  pCommPacket->RTEHeader.RTEFlags        = RSQL_NORMAL;
  pCommPacket->RTEHeader.ResidualPackets = 0;
  pCommPacket->RTEHeader.SenderRef       = pShmConnInfo->ulClientRef;
  pCommPacket->RTEHeader.ReceiverRef     = pShmConnInfo->ulServerRef;
  pCommPacket->RTEHeader.RTEReturnCode   = SQLOK;
  pCommPacket->RTEHeader.Filler          = 0;
  pCommPacket->RTEHeader.MaxSendLen      = (INT4)ulCmdDataLen +
                                           RTE_HEADER_SIZE;

  //
  // - set some communication segment values and post the
  //   communication flag to signal that data has been send to server
  //
  pCSHeader->ulClientCommState   = SQLOK;
  pCSHeader->ulCurrentPacket     = pShmConnInfo->ulCurrentPacket;
  pCSHeader->ulClientFlag        = 1;

  if ( pShmConnInfo->pulCommFlag != NULL )
    *pShmConnInfo->pulCommFlag   = 1;

  // ---  Wake up the UKT?
  if (( pShmConnInfo->pulSemaFlag  == NULL ) ||
      ( *pShmConnInfo->pulSemaFlag == POST_SEM ))
    {
    ulCommState = sql33c_post_server_sem (pShmConnInfo->hevServerSem, pErrText);

    if ( ulCommState != SQLOK )
      {
      DBGOUT;
      return ( ulCommState );
      }
    }

  DBG3 (( MF__, "ulServerCommState: %d", pCSHeader->ulServerCommState  ));
  DBG3 (( MF__, "ulClientCommState: %d", pCSHeader->ulClientCommState  ));
  DBG3 (( MF__, "ulServerFlag     : %d", pCSHeader->ulServerFlag ));
  DBG3 (( MF__, "ulClientFlag     : %d", pCSHeader->ulClientFlag ));

  DBGOUT;
  return ( SQLOK );
  }


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

#if defined(KERNEL)

 ULONG  sql33c_reply ( PSHM_CONNECT_INFO_REC   pShmConnInfo,
                       PTASK_CTRL_REC          pTaskCtrl,
                       ERRORTEXT               pErrText )
   {
   #undef  MF__
   #define MF__ MOD__"sql33c_reply"
   PCOMM_SEG_HEADER_REC           pCSHeader;

   pCSHeader               = pShmConnInfo->pCSHeader;
   pTaskCtrl->fTimeOut     = FALSE;
   pTaskCtrl->ulCOMTimeOut = MIN_COMMAND_TIMEOUT + kgs.ulCurrTime;

   do
     {
     // --- insert task into COM queue, where it waits for a reply
     sql73k_COM_enqu (pTaskCtrl->pUKT, pTaskCtrl);

     GOTO_DISP( pTaskCtrl->pUKT );

     if ( ! kgs.fNetRestarted )
       {
       MSGD (( IERR_NETW_NOT_RESTARTED, "sql33c_reply" ))
       sql46c_build_error_string ( pErrText, ERRMSG_NETW_NOT_RESTARTED, 0);
       DBGOUT;
       return ( SQLSEND_LINE_DOWN );
       }

     if ( pTaskCtrl->fTimeOut == TRUE )
       {
       pTaskCtrl->fTimeOut = FALSE;
       MSGD (( ERR_REPLY_TIMEOUT ))
       sql46c_build_error_string ( pErrText, ERRMSG_REPLY_TIMEOUT, 0);
       DBGOUT;
       return ( SQLTIMEOUT );
       }
     }
   while ( pCSHeader->ulServerFlag != 1 );

   // --- signal that we received the data
   pCSHeader->ulClientFlag = 0;
   pCSHeader->ulServerFlag = 2;

   if ( pCSHeader->ulServerCommState != SQLOK )
     {
     sql46c_build_error_string ( pErrText, ERRMSG_COM_CONN_BROKEN, 0 );
     DBGOUT;
     return ( pCSHeader->ulServerCommState );
     }

   DBGOUT;
   return ( SQLOK );
   }

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

 ULONG sql33c_crash_cleanup ( PSHM_CONNECT_INFO_REC   pShmConnInfo,
                              ERRORTEXT               pErrText )
   {
   #undef  MF__
   #define MF__ MOD__"sql33c_crash_cleanup"
   APIRET                          rc          = NO_ERROR;
   PCOMM_SEG_HEADER_REC            pCSHeader;
   ULONG                          ulCommState;

   DBGIN;

   pCSHeader = pShmConnInfo->pCSHeader;

   if ( pCSHeader != NULL )
      {
      //
      // - set some communication segment values and post the
      //   communication flag to signal a event
      //
      pCSHeader->pidClientOrPeerPID = (PID)UNDEF;
      pCSHeader->ulClientCommState  = SQLSEND_LINE_DOWN;
      pCSHeader->ulClientFlag       = 1;

      if ( pShmConnInfo->pulCommFlag != NULL )
        *pShmConnInfo->pulCommFlag = 1;

      if ( pShmConnInfo->hevServerSem != (HEV) INVALID_HANDLE_VALUE )
        {
        ulCommState =  sql33c_post_server_sem( pShmConnInfo->hevServerSem,
                                               pErrText );
        }
      }

   DBGOUT;
   return ( SQLSEND_LINE_DOWN );
   }

#else

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

 ULONG  sql33c_replyavailable( PSHM_CONNECT_INFO_REC   pShmConnInfo,
                               ERRORTEXT               pErrText )
   {
   #undef  MF__
   #define MF__ MOD__"sql33c_replyavailable"
   PCOMM_SEG_HEADER_REC            pCSHeader;

   DBGIN;

   pCSHeader = pShmConnInfo->pCSHeader;

   if ( pCSHeader->ulClientFlag == 0 )
     {
     MSGD (( ERR_UNBAL_REQUEST_REPLY ));
     sql46c_build_error_string(pErrText, ERRMSG_COM_UNBALANCED_REQUEST_REPLY, 0);

     return ( SQLNOTOK );
     }

   DBG3 (( MF__, "ulServerCommState: %d", pCSHeader->ulServerCommState  ));
   DBG3 (( MF__, "ulServerFlag     : %d", pCSHeader->ulServerFlag ));
   DBG3 (( MF__, "ulClientFlag     : %d", pCSHeader->ulClientFlag ));

   if ( pCSHeader->ulServerFlag != 1 )
     {
     DBGOUT;
     return ( SQLWOULDBLOCK );
     }

   DBGOUT;
   return ( SQLOK );
   }

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

 ULONG  sql33c_receive ( PSHM_CONNECT_INFO_REC   pShmConnInfo,
                         PCOMM_PACKET_REC        *ppResPacket,
                         PULONG                  pulResDataLen,
                         ERRORTEXT               pErrText )
   {
   #undef  MF__
   #define MF__ MOD__"sql33c_receive"
   APIRET                          rc                = NO_ERROR;
   ULONG                           ulCommState;
   PCOMM_SEG_HEADER_REC            pCSHeader;
   PCOMM_PACKET_REC                pCmdCommPacket;
   PRTE_HEADER_REC                 pRTEHeader;

   DBGIN;

   pCSHeader = pShmConnInfo->pCSHeader;

   DBG3 (( MF__, "ulServerCommState: %d", pCSHeader->ulServerCommState  ));
   DBG3 (( MF__, "ulClientCommState: %d", pCSHeader->ulClientCommState  ));
   DBG3 (( MF__, "ulServerFlag     : %d", pCSHeader->ulServerFlag ));
   DBG3 (( MF__, "ulClientFlag     : %d", pCSHeader->ulClientFlag ));

   if ( pCSHeader->ulClientFlag == 0 )
     {
     MSGD (( ERR_UNBAL_REQUEST_REPLY ));
     sql46c_build_error_string(pErrText, ERRMSG_COM_UNBALANCED_REQUEST_REPLY, 0);

     return ( SQLNOTOK );
     }

   while ( pCSHeader->ulServerFlag != 1 )
     {
     ulCommState = sql33c_wait_client_sem ( pShmConnInfo->hevClientSem,
                                           (ULONG)-1, pErrText );

     if ( ulCommState != SQLOK )
       {
       DBGOUT;
       return ( ulCommState );
       }
     }

   // --- signal that we have received
   pCSHeader->ulServerFlag = 2;

   if ( pCSHeader->ulServerCommState != SQLOK )
     {
     if ( pCSHeader->ulServerCommState == SQLTIMEOUT )
       {
       MSGD (( INFO_COM_TIMEOUT ));
       sql46c_build_error_string ( pErrText, ERRMSG_COM_TIMEOUT, 0 );
       DBGOUT;
       return ( SQLTIMEOUT );
       }
     else
       {
       sql46c_build_error_string ( pErrText, ERRMSG_COM_CONN_BROKEN, 0 );
       DBGOUT;
       return ( pCSHeader->ulServerCommState );
       }
     }

   // --- get the result packet position.
   //
   pCmdCommPacket = pShmConnInfo->pCommPacketList[pShmConnInfo->ulCurrentPacket];
   *ppResPacket   = (PCOMM_PACKET_REC) ((PCHAR)pCmdCommPacket->pDataPart +
                                       ALIGN ( pShmConnInfo->ulCmdDataLen, SQL_PACKET_ALIGNMENT));
   pRTEHeader     = &(*ppResPacket)->RTEHeader;
   *pulResDataLen = pRTEHeader->ActSendLen - RTE_HEADER_SIZE;
   ulCommState    = (ULONG)pRTEHeader->RTEReturnCode;

   if (( pCSHeader->ulClientFlag != 2 )              ||
       ( pRTEHeader->MaxSendLen  < RTE_HEADER_SIZE ) ||
       ( pRTEHeader->SenderRef   == UNDEF ))
     {
     // --- the kernel has released the connection without a reply.
     sql46c_build_error_string ( pErrText, ERRMSG_COM_CONN_BROKEN, 0 );
     DBGOUT;
     return ( SQLNOTOK );
     }

   if ( pShmConnInfo->ulServiceType == SQL_DISTRIBUTION )
     {
     // --- RTE-Header check
     if (( pRTEHeader->ResidualPackets    != 0 )                         ||
         ( (ULONG)pRTEHeader->SenderRef   != pShmConnInfo->ulServerRef ) ||
         ( (ULONG)pRTEHeader->ReceiverRef != pShmConnInfo->ulClientRef ) ||
         ( pRTEHeader->MessClass          != RSQL_KERN_DATA_REPLY )      ||
         ( pRTEHeader->MaxSendLen         != pRTEHeader->ActSendLen ))
       {
       MSGD (( ERR_PROTOCOL_ERROR, "sql33c_receive" ));
       sql46c_build_error_string ( pErrText, ERRMSG_PROTOCOL_ERROR, 0 );

       DBGOUT;
       return ( SQLNOTOK );
       }
     }
   else
     {
     // --- RTE-Header check
     if (( pRTEHeader->ResidualPackets    != 0 )                         ||
         ( (ULONG)pRTEHeader->SenderRef   != pShmConnInfo->ulServerRef ) ||
         ( (ULONG)pRTEHeader->ReceiverRef != pShmConnInfo->ulClientRef ) ||
         ( pRTEHeader->MessClass          != RSQL_USER_DATA_REPLY )      ||
         ( pRTEHeader->ProtocolID         != RSQL_RTE_PROT_UNDEF )       ||
         ( pRTEHeader->MaxSendLen         != pRTEHeader->ActSendLen ))
       {
       MSGD (( ERR_PROTOCOL_ERROR, "sql33c_receive" ));
       sql46c_build_error_string ( pErrText, ERRMSG_PROTOCOL_ERROR, 0 );

       DBGOUT;
       return ( SQLNOTOK );
       }
     }

   // --- signal that we are ready for the next request
   pCSHeader->ulClientFlag = 0;

   DBG3 (( MF__, "ulServerCommState: %d", pCSHeader->ulServerCommState  ));
   DBG3 (( MF__, "ulClientCommState: %d", pCSHeader->ulClientCommState  ));
   DBG3 (( MF__, "ulServerFlag     : %d", pCSHeader->ulServerFlag ));
   DBG3 (( MF__, "ulClientFlag     : %d", pCSHeader->ulClientFlag ));

   DBGOUT;
   return ( SQLOK );
   }

#endif

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

ULONG sql33c_cancel_dump ( PSHM_CONNECT_INFO_REC   pShmConnInfo,
                           ULONG                   ulReqType,
                           ERRORTEXT               pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql33c_cancel_dump"
  ULONG                           ulCommState;

  DBGIN;

  //
  // --- send a cancel/dump request
  //
  ulCommState = sql33c_write_queue_mailslot( pShmConnInfo->hQueMailSlot,
                                            NULL,
                                            ulReqType,
                                            pShmConnInfo->ulServerRef,
                                            0,
                                            pErrText );

  DBGOUT;
  return ( ulCommState );
  }

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

ULONG sql33c_release ( PSHM_CONNECT_INFO_REC   pShmConnInfo,
                       ERRORTEXT               pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql33c_release"
  ULONG                           ulCommState = SQLOK;
  APIRET                          rc          = NO_ERROR;
  PCOMM_SEG_HEADER_REC            pCSHeader;

  DBGIN;

  pCSHeader = pShmConnInfo->pCSHeader;

  if ( pCSHeader != NULL )
     {
     //
     // - set some communication segment values and post the
     //   communication flag to signal a event
     //
     pCSHeader->pidClientOrPeerPID = (PID)UNDEF;

     if ( pShmConnInfo->pulCommFlag != NULL )
       *pShmConnInfo->pulCommFlag  = 1;

     if ( pShmConnInfo->hevServerSem != (HEV) INVALID_HANDLE_VALUE )
       {
       ulCommState =  sql33c_post_server_sem( pShmConnInfo->hevServerSem,
                                              pErrText );
       }

     if ( ulCommState == SQLOK )
       ulCommState = sql33c_free_comm_seg( pShmConnInfo->hCS,
                                           pShmConnInfo->pCSHeader,
                                           pErrText );
     }

  if ( ulCommState == SQLOK )
    ulCommState = sql33c_close_queue_mailslot ( pShmConnInfo->hQueMailSlot,
                                                pErrText );

  #if !defined (KERNEL)
   if ( ulCommState == SQLOK )
     ulCommState = sql33c_close_client_sem     ( pShmConnInfo->hevClientSem,
                                                 pErrText );
  #endif

  if ( ulCommState == SQLOK )
    ulCommState = sql33c_close_server_sem     ( pShmConnInfo->hevServerSem,
                                                pErrText );
  if (( ulCommState == SQLOK ) && ( pShmConnInfo->pFCS != NULL ))
    ulCommState = sql33c_free_flag_comm_seg ( pShmConnInfo->hFCS,
                                              pShmConnInfo->pFCS,
                                              pErrText );
  if ( ulCommState != SQLOK )
    {
    // --- close without error handling !
    sql33c_close_queue_mailslot ( pShmConnInfo->hQueMailSlot, NULL );
    sql33c_close_server_sem     ( pShmConnInfo->hevServerSem, NULL );

    #if !defined (KERNEL)
     sql33c_close_client_sem    ( pShmConnInfo->hevClientSem, NULL );
    #endif
    }

  pShmConnInfo->hCS          = INVALID_HANDLE_VALUE;
  pShmConnInfo->pCSHeader    = NULL;
  pShmConnInfo->hFCS         = INVALID_HANDLE_VALUE;
  pShmConnInfo->pFCS         = NULL;
  pShmConnInfo->hQueMailSlot = INVALID_HANDLE_VALUE;
  pShmConnInfo->hevServerSem = (HEV)INVALID_HANDLE_VALUE;
  pShmConnInfo->hevClientSem = (HEV)INVALID_HANDLE_VALUE;
  pShmConnInfo->ulServerRef  = (ULONG)UNDEF;

  DBGOUT;
  return ( ulCommState );
  }

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

#if defined (OS2) && defined (KERNEL)   // - ignore unused parameter
# pragma info (nopar)
#endif

static ULONG sql33c_connect_wait ( HEV                   hevClientSem,
                                   ULONG                 ulServiceType,
                                   ULONG                 ulTimeOut,
                                   PCOMM_SEG_HEADER_REC  pCSHeader,
                                   ERRORTEXT             pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql33c_connect_wait"
  ULONG                           ulCommState = SQLOK;
  #if defined (KERNEL)
   PUKT_CTRL_REC                  pUKT        = THIS_UKT_CTRL;
   PTASK_CTRL_REC                 pTaskCtrl   = pUKT->pCTask;
  #endif

  DBGIN;


  #if defined (KERNEL)
    /*
     *  insert task into COM queue, where it waits for the connect reply.
     */
    pTaskCtrl->ulCOMTimeOut = ulTimeOut + kgs.ulCurrTime;
    pTaskCtrl->fTimeOut     = FALSE;

    do
      {
      sql73k_COM_enqu ( pUKT, pTaskCtrl );

      GOTO_DISP ( pUKT );

      if ( ! kgs.fNetRestarted )
        {
        MSGD (( IERR_NETW_NOT_RESTARTED, "connect wait" ))
        sql46c_build_error_string ( pErrText, ERRMSG_NETW_NOT_RESTARTED, 0);
        DBGOUT;
        return ( SQLSEND_LINE_DOWN );
        }

      if ( pTaskCtrl->fTimeOut == TRUE )
        {
        pTaskCtrl->fTimeOut = FALSE;
        MSGD (( ERR_CONN_TIMEOUT ))
        sql46c_build_error_string ( pErrText, ERRMSG_CONNECT_TIMED_OUT, 0 );
        DBGOUT;
        return ( SQLTIMEOUT );
        }
      }
    while (( pCSHeader->ulServerFlag       != 1 )          &&
           ( pCSHeader->pidClientOrPeerPID != (PID)UNDEF ) &&
           ( pCSHeader->ulServerCommState  == SQLOK ));
  #else
   if ( ulTimeOut != (ULONG)UNDEF )
     ulTimeOut *= 1000;

   ulCommState = sql33c_wait_client_sem ( hevClientSem, ulTimeOut, pErrText );
  #endif

  DBGOUT;
  return ( ulCommState );
  }

#if defined (OS2) && defined (KERNEL)   // - ignore unused parameter
# pragma info (restore)
#endif

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

static ULONG  sql33c_open_queue_mailslot ( PSZ                    pszQueName,
                                           BOOL                   fConnectToXServer,
                                           PID                    *ppidServer,
                                           PHANDLE                phQueMailSlot,
                                           ERRORTEXT              pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql33c_open_queue_mailslot"
  PSZ         pszPath;
  APIRET      rc = NO_ERROR;

  DBGIN;

  //
  // --- open mailslot / fifo queue
  //
  #if defined(_WIN32)
   pszPath = MAIL_REQ;
  #else
   pszPath = QUE_REQ;
  #endif

  rc = sql41c_open_queue_mailslot ( ppidServer,   // - OS/2
                                    phQueMailSlot,
                                    pszPath,
                                    pszQueName );

  if ( rc == ERROR_FILE_NOT_FOUND )
    {
    *phQueMailSlot = INVALID_HANDLE_VALUE;

    if ( fConnectToXServer )
      {
      MSGD (( ERR_XSERVER_NOT_ACTIVE ));
      sql46c_build_error_string ( pErrText, ERRMSG_XSERVER_NOT_ACTIVE, 0 );
      }
    else
      {
      MSGD (( ERR_DATABASE_NOT_STARTED, pszQueName ));
      sql46c_build_error_string ( pErrText, ERRMSG_COM_DATABASE_NOT_STARTED, 0 );
      }

    DBGOUT;
    return ( SQLSTART_REQUIRED );
    }

  if ( rc != NO_ERROR )
    {
    *phQueMailSlot = INVALID_HANDLE_VALUE;
    sql46c_build_error_string ( pErrText, ERRMSG_COM_SERVER_OR_DB_NOT_ACC, rc );

    DBGOUT;
    return ( SQLNOTOK );
    }

  DBGOUT;
  return ( SQLOK );
  }

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

static ULONG  sql33c_write_queue_mailslot ( HANDLE             hQueMailSlot,
                                            PSZ                pszClientObjName,
                                            ULONG              ulReqType,
                                            ULONG              ulServerRef,
                                            ULONG              ulCSSize,
                                            ERRORTEXT          pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql33c_write_queue_mailslot"
  APIRET              rc = NO_ERROR;
  COMM_REQUEST_REC    Request;

  DBGIN;

  //
  //
  // --- send a connect request
  //
  //
  #if defined(_WIN32)
   Request.ulReqType               = ulReqType;
   Request.ulServerRef             = ulServerRef;
   Request.ulCSSize                = ulCSSize;

   if ( pszClientObjName != NULL )
     strcpy ( Request.szClientObjName, pszClientObjName );
   else
     Request.szClientObjName[0] = '\0';
  #else
   Request.BitFields.bf4Type       = ulReqType;
   Request.BitFields.bf28ServerRef = ulServerRef;
  #endif

  rc = sql41c_write_queue_mailslot ( hQueMailSlot,
                                     &Request,
                                     sizeof (COMM_REQUEST_REC),
                                     ulCSSize,      // - OS/2 only
                                     pErrText );

  if ( rc != NO_ERROR )
    {
    DBG1 (( MF__, "ERROR: 'sql41c_write_queue_mailslot', rc =  %d", rc ));

    if (( rc == ERROR_HANDLE_EOF ) || ( rc == ERROR_FILE_NOT_FOUND ))
      sql46c_build_error_string ( pErrText, ERRMSG_COM_SERVER_OR_DB_NOT_ACC, 0 );
    else
      sql46c_build_error_string ( pErrText, ERRMSG_COM_CANT_WRITE_COM_QUE, rc );

    DBGOUT;
    return ( SQLNOTOK );
    }

  DBGOUT;
  return ( SQLOK );
  }


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

static ULONG sql33c_close_queue_mailslot ( HANDLE      hQueMailSlot,
                                           ERRORTEXT   pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql33c_close_queue_mailslot"
  APIRET    rc          = NO_ERROR;
  ULONG     ulCommState = SQLOK;

  DBGIN;

  if ( hQueMailSlot != INVALID_HANDLE_VALUE )
    {
    rc = sql41c_close_queue_mailslot ( hQueMailSlot );

    if ( rc != NO_ERROR )
      {
      ulCommState = SQLNOTOK;

      if ( pErrText != NULL )
        sql46c_build_error_string ( pErrText, ERRMSG_COM_CLOSE_QUE_MAIL, rc );
      }
    }

  DBGOUT;
  return ( ulCommState );
  }

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

#if !defined (KERNEL)

 static ULONG  sql33c_create_client_sem( PSZ                   pszSemPath,
                                         PSZ                   pszClientObjName,
                                         PHEV                  phevClientSem,
                                         PSECURITY_ATTRIBUTES  pWorldSA,
                                         ERRORTEXT             pErrText )
   {
   #undef  MF__
   #define MF__ MOD__"sql33c_create_client_sem"
   APIRET      rc      = NO_ERROR;
   #if defined(_WIN32)
    ULONG      ulRetry = 10;
   #endif

   DBGIN;

   //
   // --- create event semaphore
   //
   #if defined(_WIN32)
    do
      {
      rc = sql41c_create_event_sem ( phevClientSem,
                                     pszSemPath, pszClientObjName,
                                     CREATE_EVENT_SEM_SHARED, 0,
                                     pWorldSA );

      // --- unique name already in use?
      if ( rc == ERROR_DUPLICATE_NAME )
        {
        SLEEP ( 1 );

        // -- build a new unique name
        sql41c_build_unique_obj_name ( pszClientObjName );
        }
      }
    while (( rc == ERROR_DUPLICATE_NAME ) && (--ulRetry) );

   #else
    rc = sql41c_create_event_sem ( phevClientSem,
                                   NULL, NULL,
                                   CREATE_EVENT_SEM_SHARED, 0,
                                   NULL );
   #endif


   if ( rc != NO_ERROR )
     {
     *phevClientSem = INVALID_HANDLE_VALUE;
     DBG1 (( MF__, "ERROR: create event sem, rc =  %d", rc ));
     MSGD (( ERR_CANT_CREATE_COM_SEM, rc ));
     sql46c_build_error_string ( pErrText, ERRMSG_COM_CANT_CREATE_COM_SEM, rc );

     DBGOUT;
     return ( SQLNOTOK );
     }


   DBGOUT;
   return ( SQLOK );
   }

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

 static ULONG  sql33c_wait_client_sem ( HEV        hevClientSem,
                                        ULONG      ulTimeOut,
                                        ERRORTEXT  pErrText )
   {
   #undef  MF__
   #define MF__ MOD__"sql33c_wait_client_sem"
   APIRET      rc      = NO_ERROR;

   DBGIN;

   rc =  sql41c_wait_event_sem ( hevClientSem, ulTimeOut, "Client" );

   if ( rc != NO_ERROR )
     {
     if ( rc == ERROR_TIMEOUT )
       {
       MSGD (( ERR_CONN_TIMEOUT ));
       sql46c_build_error_string ( pErrText, ERRMSG_CONN_TIMEOUT, 0 );
       }
     else
       {
       MSGD (( ERR_WAIT_COM_SEM, rc ));
       sql46c_build_error_string ( pErrText, ERRMSG_COM_WAIT_COM_SEM, rc );
       }
     DBGOUT;
     return ( SQLNOTOK );
     }

   DBGOUT;
   return ( SQLOK );
   }

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

 static ULONG sql33c_close_client_sem ( HEV        hevClientSem,
                                        ERRORTEXT  pErrText )
   {
   #undef  MF__
   #define MF__ MOD__"sql33c_close_client_sem"
   APIRET    rc          = NO_ERROR;
   ULONG     ulCommState = SQLOK;

   DBGIN;

   if ( hevClientSem != (HEV)INVALID_HANDLE_VALUE )
     {
     rc = sql41c_close_event_sem ( hevClientSem, "Client" );

     if ( rc != NO_ERROR )
       {
       ulCommState = SQLNOTOK;

       if ( pErrText != NULL )
         sql46c_build_error_string ( pErrText, ERRMSG_COM_CLOSE_CLIENT_SEM, rc );
       }
     }

   DBGOUT;
   return ( ulCommState );
   }
#endif

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

static ULONG  sql33c_open_server_sem ( PSZ            pszSemPath,
                                       PSZ            pszSemName,
                                       PHEV           phevServerSem,
                                       ERRORTEXT      pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql33c_open_server_sem"
  PSZ         pszPath;
  PSZ         pszName;
  APIRET      rc      = NO_ERROR;

  DBGIN;

  //
  // --- create event semaphore
  //
  #if defined(_WIN32)
   pszPath = pszSemPath;
   pszName = pszSemName;
  #else
   pszPath = NULL;
   pszName = NULL;
  #endif

  rc = sql41c_open_event_sem ( phevServerSem, pszPath, pszName, NO_ERROR );


  if ( rc != NO_ERROR )
    {
    *phevServerSem = INVALID_HANDLE_VALUE;
    DBG1 (( MF__, "ERROR: open event sem, rc =  %d", rc ));
    MSGD (( ERR_CANT_OPEN_UKT_SEM, rc ));
    sql46c_build_error_string ( pErrText, ERRMSG_COM_CANT_OPEN_UKT_SEM, rc );

    DBGOUT;
    return ( SQLNOTOK );
    }

  DBGOUT;
  return ( SQLOK );
  }

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

static ULONG  sql33c_post_server_sem ( HEV            hevServerSem,
                                       ERRORTEXT      pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql33c_post_server_sem"
  APIRET      rc = NO_ERROR;

  DBGIN;

  // ---  Wake up the UKT!
  rc = sql41c_post_event_sem ( hevServerSem, "Server" );

  if (( rc != NO_ERROR ) && ( rc != ERROR_ALREADY_POSTED ))
    {
    DBG1 (( MF__, "ERROR: Posting event sem, rc =  %d", rc ));
    sql46c_build_error_string ( pErrText, ERRMSG_COM_POST_UKT_SEM, rc );

    DBGOUT;
    return ( SQLNOTOK );
    }

  DBGOUT;
  return ( SQLOK );
  }

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

static ULONG sql33c_close_server_sem ( HEV        hevServerSem,
                                       ERRORTEXT  pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql33c_close_server_sem"
  APIRET    rc          = NO_ERROR;
  ULONG     ulCommState = SQLOK;

  DBGIN;

  if ( hevServerSem != (HEV)INVALID_HANDLE_VALUE )
    {
    rc = sql41c_close_event_sem ( hevServerSem, "Server" );

    if ( rc != NO_ERROR )
      {
      ulCommState = SQLNOTOK;

      if ( pErrText != NULL )
        sql46c_build_error_string ( pErrText, ERRMSG_COM_CLOSE_SERV_SEM, rc );
      }
    }

  DBGOUT;
  return ( ulCommState );
  }

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

static ULONG  sql33c_create_comm_seg( ULONG                 ulCSSize,
                                      PSZ                   pszClientObjName,
                                      PSECURITY_ATTRIBUTES  pWorldSA,
                                      PID                   pidServer,
                                      PHANDLE               phCS,
                                      PCOMM_SEG_HEADER_REC  *ppCSHeader,
                                      ERRORTEXT             pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql33c_create_comm_seg"
  PSZ                       pszPath;
  PSZ                       pszName;
  APIRET                    rc      = NO_ERROR;

  DBGIN;

  //
  //
  // --- alloc shared communication memory segment with "world access"
  //
  //
  #if defined(_WIN32)
   pszPath = SHM_COMMSEG;
   pszName = pszClientObjName;
  #else
   pszPath = NULL;
   pszName = NULL;
  #endif

  rc = sql41c_create_shrd_mem ( (PVOID*) ppCSHeader, ulCSSize,
                                pszPath, pszName,
                                pWorldSA,            // - WIN32 only
                                phCS );              // - WIN32 only

  if ( rc != NO_ERROR )
    {
    DBG1 (( MF__, "ERROR: 'CreateSharedMem', rc =  %d", rc ));
    *ppCSHeader = NULL;
    *phCS       = INVALID_HANDLE_VALUE;

    MSGD (( ERR_CANT_ALLOC_COM_SEG, rc ));
    sql46c_build_error_string ( pErrText, ERRMSG_COM_CANT_ALLOC_COM_SEG, rc );

    DBGOUT;
    return ( SQLPACKETLIMIT );
    }

  //
  //
  // --- set access rights of the shared communication memory segment
  //     ( OS/2 only )
  //
  //
  #if !defined(_WIN32)
   rc = sql41c_give_shrd_mem ( *ppCSHeader, pidServer, NULL, NULL );

   if ( rc != NO_ERROR )
     {
     sql33c_free_comm_seg( *phCS, *ppCSHeader, NULL );
     sql46c_build_error_string ( pErrText, ERRMSG_COM_CANT_GIVE_COM_SEG, rc );
     DBGOUT;
     return ( SQLNOTOK );
     }
  #endif

  DBGOUT;
  return ( SQLOK );
  }

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

static ULONG  sql33c_lock_comm_seg( HANDLE                   hCS,
                                    PSECURITY_ATTRIBUTES     pLockSA,
                                    ERRORTEXT                pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql33c_lock_comm_seg"
  APIRET    rc      = NO_ERROR;

  DBGIN;

  #if defined(_WIN32)
   // --- set security descriptor with "no access"
   rc = sql49c_set_kernel_obj_sec ( pLockSA->lpSecurityDescriptor, hCS );

   if ( rc != NO_ERROR )
     {
     DBG1 (( MF__, "ERROR: 'sql49c_set_kernel_obj_sec', rc =  %d", rc ));
     sql46c_build_error_string ( pErrText, ERRMSG_COM_CANT_SET_OBJ_SEC, rc );

     DBGOUT;
     return ( SQLNOTOK );
     }
  #endif

  DBGOUT;
  return ( SQLOK );
  }

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

static ULONG  sql33c_free_comm_seg( HANDLE                hCS,
                                    PCOMM_SEG_HEADER_REC  pCSHeader,
                                    ERRORTEXT             pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql33c_free_comm_seg"
  APIRET    rc          = NO_ERROR;
  ULONG     ulCommState = SQLOK;


  DBGIN;


  if ( pCSHeader != NULL )
    {
    rc = sql41c_free_shrd_mem ( pCSHeader, hCS );

    if ( rc != NO_ERROR )
      {
      ulCommState = SQLNOTOK;

      if ( pErrText != NULL )
        sql46c_build_error_string ( pErrText, ERRMSG_COM_CANT_FREE_MEM, rc );
      }
    }

  DBGOUT;
  return ( ulCommState );
  }

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

static VOID sql33c_init_comm_seg ( PSHM_CONNECT_INFO_REC    pShmConnInfo,
                                   PSZ                      pszClientObjName,
                                   PSZ                      pszClientSemPath,
                                   PSZ                      pszClientSemName,
                                   ERRORTEXT                pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql33c_init_comm_seg"
  ULONG                 ulCnt;
  PCOMM_SEG_HEADER_REC  pCSHeader;
  PCOMM_SEG_OFFSET_REC  pCSOffsetList;

  DBGIN;

  //
  // - Structure of the communication segment
  //
  //      +------------------------------------+
  //   +--|     comm_seg_header_record         |
  //   |  +------------------------------------+
  //   +->|     comm_seg_offset_record         |--+
  //      +------------------------------------+  |
  //      | 1.  comm_packet_record             |<-+
  //      |     (request)                      |  |
  //      |  --------------------------------  |  |
  //      |     comm_packet_record             |  |
  //      |     (receive)                      |  |
  //      +------------------------------------+  |
  //      .                                    .  .
  //      .                                    .  .
  //      +------------------------------------+  |
  //      | n.  comm_packet_record             |<-+
  //      |     (request)                      |
  //      |  --------------------------------  |
  //      |     comm_packet_record             |
  //      |    /(receive)                      |
  //      +---/--------------------------------+
  //         /
  //        /
  // +-----+------------------------------+
  // |     rte_header_record +            |
  // |     sql_packet (data)              |
  // +------------------------------------+
  //
  //  n = MAX_SQL_PACKETS
  //

  //
  // --- init the communication segment header
  //
  pCSHeader                     = pShmConnInfo->pCSHeader;
  pCSHeader->iCSVersion         = COMM_SEG_VERSION;
  pCSHeader->ulCSSize           = pShmConnInfo->ulCSSize;
  pCSHeader->ulPacketCnt        = pShmConnInfo->ulPacketCnt;
  pCSHeader->ulPacketSize       = pShmConnInfo->ulPacketSize;
  pCSHeader->ulMaxDataLen       = pShmConnInfo->ulMaxDataLen;
  pCSHeader->ulMinReplySize     = pShmConnInfo->ulMinReplySize;
  pCSHeader->ulOffsetRecord     = COMM_SEG_HEADER_SIZE;
  pCSHeader->ulCurrentPacket    = 0;
  pCSHeader->pidClientOrPeerPID = pShmConnInfo->pidClientPID;
  pCSHeader->pidServerPID       = (ULONG)UNDEF;
  pCSHeader->ulClientOrPeerRef  = pShmConnInfo->ulClientRef;
  pCSHeader->ulServerRef        = (ULONG)UNDEF;
  pCSHeader->ulClientCommState  = SQLOK;
  pCSHeader->ulServerCommState  = SQLOK;
  pCSHeader->ulClientFlag       = 0;
  pCSHeader->ulServerFlag       = 0;
  pCSHeader->ulServiceType      = pShmConnInfo->ulServiceType;
  pCSHeader->ulCommFlagNo       = pShmConnInfo->ulCommFlagNo;

  // -- operating system specific part
  strcpy ( pCSHeader->szClientOrPeerNode, pShmConnInfo->szClientNode );

  #if defined(_WIN32)
   GETPROCESSID (&pCSHeader->pidLocalPID);
   strcpy ( pCSHeader->szSemPath, pszClientSemPath );
   strcpy ( pCSHeader->szSemName, pszClientSemName );
  #else
   pCSHeader->hevClientSem       = pShmConnInfo->hevClientSem;
   pCSHeader->hevServerSem       = (HEV)INVALID_HANDLE_VALUE;
  #endif

  // -- distribution only
  if ( pShmConnInfo->ulServiceType == SQL_DISTRIBUTION )
    {
    strcpy ( pCSHeader->szServerNode, pShmConnInfo->szServerNode );
    strcpy ( pCSHeader->szServerDB, pShmConnInfo->szServerDB );

    #if defined(KERNEL)
     strcpy ( pCSHeader->szClientOrPeerServerDB, kgs.szServerDB );
    #else
     pCSHeader->szClientOrPeerServerDB[0] = '\0';
    #endif
    }

  //
  // --- initialize the offset record and save the pointers of
  //     the communication segment parts
  //

  // --- calculate the start address of the 'offset list'
  pCSOffsetList              = (PCOMM_SEG_OFFSET_REC)
                               ((PCHAR)pCSHeader + COMM_SEG_HEADER_SIZE);
  pCSOffsetList->ulOffsetCnt = pShmConnInfo->ulPacketCnt;
  pCSOffsetList->ulOffset[0] = ALIGN ( COMM_SEG_HEADER_SIZE  +
                                       COMM_OFFSET_LIST_SIZE +
                                       ALIGNMENT_VALUE,
                                       ALIGNMENT_VALUE );

  for ( ulCnt = 1; ulCnt < pShmConnInfo->ulPacketCnt; ulCnt++ )
    {
    pCSOffsetList->ulOffset[ulCnt]      = pCSOffsetList->ulOffset[ulCnt-1] +
                                          (RTE_HEADER_SIZE * 2)            +
                                          pShmConnInfo->ulMaxDataLen;
    }

  DBGOUT;
  return;
  }

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

static VOID sql33c_calculate_sizes ( ULONG                  ulPacketCnt,
                                     ULONG                  ulMaxPacketSize,
                                     PULONG                 pulPacketSize,
                                     PULONG                 pulMaxDataLen,
                                     PULONG                 pulCSSize )
  {
  #undef  MF__
  #define MF__ MOD__"sql33c_calculate_sizes"
  ULONG                           ulHeaderSize;
  ULONG                           ulMaxDataLen;
  ULONG                           ulCSSize;

  DBGIN

  // --- calculate the required header size
  ulHeaderSize = ALIGN ( COMM_SEG_HEADER_SIZE  + COMM_OFFSET_LIST_SIZE +
                         ALIGNMENT_VALUE, ALIGNMENT_VALUE ) +
                 (ulPacketCnt * RTE_HEADER_SIZE * 2);


  if ( ulMaxPacketSize == (ULONG)UNDEF )
    {
    if ( *pulPacketSize != 0 )
      {
      ulCSSize       = *pulPacketSize * ulPacketCnt;
      ulMaxDataLen   = (ulCSSize - ulHeaderSize) / ulPacketCnt;

      if ( *pulMaxDataLen > ulMaxDataLen )
        *pulMaxDataLen = ulMaxDataLen;

      *pulMaxDataLen = ALIGN(*pulMaxDataLen + 1,ALIGNMENT_VALUE) -
                       ALIGNMENT_VALUE;
      }
    else
      *pulMaxDataLen = 0;
    }
  else if ( *pulPacketSize == 0 )
    {
    *pulPacketSize = ulMaxPacketSize;
    ulCSSize       = *pulPacketSize * ulPacketCnt;
    *pulMaxDataLen = (ulCSSize - ulHeaderSize) / ulPacketCnt;
    *pulMaxDataLen = ALIGN(*pulMaxDataLen + 1, ALIGNMENT_VALUE) -
                     ALIGNMENT_VALUE;
    }
  else
    {
    if ( *pulPacketSize > ulMaxPacketSize )
      {
      *pulMaxDataLen -= *pulPacketSize - ulMaxPacketSize;
      *pulPacketSize  = ulMaxPacketSize;
      }

    ulMaxDataLen = ((*pulPacketSize * ulPacketCnt)- ulHeaderSize)/ulPacketCnt;

    if ( *pulMaxDataLen > ulMaxDataLen )
      *pulMaxDataLen = ulMaxDataLen;

    *pulMaxDataLen   = ALIGN((*pulMaxDataLen) + 1,ALIGNMENT_VALUE) -
                       ALIGNMENT_VALUE;
    }

  *pulCSSize = *pulPacketSize * ulPacketCnt;

  DBGOUT;
  return;
  }


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

static ULONG sql33c_get_flag_comm_seg ( PSZ              pszFCSName,
                                        PHANDLE          phFCS,
                                        PFLAG_COMM_SEG   *ppFCS,
                                        ERRORTEXT        pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql33c_get_flag_comm_seg"
  APIRET                  rc = NO_ERROR;

  DBGIN;

  rc = sql41c_get_named_shrd_mem ( (PPVOID)ppFCS, SHM_FCS,
                                   pszFCSName, phFCS );

  if (( rc == ERROR_FILE_NOT_FOUND ) || ( rc == ERROR_INVALID_NAME ))
    {
    MSGD (( ERR_DATABASE_NOT_STARTED, pszFCSName ));
    sql46c_build_error_string ( pErrText, ERRMSG_COM_DATABASE_NOT_STARTED, 0 );

    DBGOUT;
    return ( SQLSTART_REQUIRED );
    }

  if ( rc != NO_ERROR )
    {
    sql46c_build_error_string ( pErrText, ERRMSG_COM_SERVER_OR_DB_NOT_ACC, rc );
    DBGOUT;
    return ( SQLNOTOK );
    }

  DBGOUT;
  return ( SQLOK );
  }

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

static ULONG sql33c_free_flag_comm_seg ( HANDLE            hFCS,
                                         PFLAG_COMM_SEG    pFCS,
                                         ERRORTEXT         pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql33c_free_flag_comm_seg"
  APIRET                  rc = NO_ERROR;

  DBGIN;

  rc = sql41c_free_shrd_mem ( pFCS, hFCS );

  if ( rc != NO_ERROR )
    {
    if ( pErrText != NULL )
      sql46c_build_error_string ( pErrText,  ERRMSG_COM_CANT_FREE_MEM, rc );

    DBGOUT;
    return ( SQLNOTOK );
    }

  DBGOUT;
  return ( SQLOK );
  }

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

static ULONG sql33c_eval_conn_reply ( PSHM_CONNECT_INFO_REC pShmConnInfo,
                                      PCONNECT_PARAM_REC    pConnParam,
                                      ERRORTEXT             pErrText )
  {
  #undef  MF__
  #define MF__ MOD__"sql33c_eval_conn_reply"
  ULONG                           ulCnt;
  PCOMM_SEG_HEADER_REC            pCSHeader;
  PCOMM_SEG_OFFSET_REC            pCSOffsetList;

  DBGIN;

  pCSHeader     = pShmConnInfo->pCSHeader;
  pCSOffsetList = (PCOMM_SEG_OFFSET_REC) ((PCHAR)pCSHeader +
                                                COMM_SEG_HEADER_SIZE);

  pShmConnInfo->ulServerRef     = pCSHeader->ulServerRef;
  pShmConnInfo->ulCommFlagNo    = pCSHeader->ulCommFlagNo;
  pShmConnInfo->pulCommFlag     = (PULONG)((PCHAR) pShmConnInfo->pFCS  +
                                  pShmConnInfo->pFCS->ulCommFlagOffset);
  pShmConnInfo->pulCommFlag    += pShmConnInfo->ulCommFlagNo;

  if ( pCSHeader->ulSemaFlagNo == (ULONG)UNDEF )
    pShmConnInfo->pulSemaFlag   = NULL;
  else
    {
    pShmConnInfo->pulSemaFlag   = (PULONG)((PCHAR) pShmConnInfo->pFCS  +
                                  pShmConnInfo->pFCS->ulSemaFlagOffset);
    pShmConnInfo->pulSemaFlag  += pCSHeader->ulSemaFlagNo;
    }


  for ( ulCnt = 0; ulCnt < pShmConnInfo->ulPacketCnt; ulCnt++ )
    {
    pShmConnInfo->pCommPacketList[ulCnt]= (PCOMM_PACKET_REC)((PCHAR)pCSHeader +
                                          pCSOffsetList->ulOffset[ulCnt]);
    }

  // --- set output parameter
  //
  pConnParam->ulServerRef       = pShmConnInfo->ulServerRef;
  pConnParam->ulPacketSize      = pShmConnInfo->ulPacketSize;
  pConnParam->ulMaxDataLen      = pShmConnInfo->ulMaxDataLen;
  pConnParam->ulMinReplySize    = pShmConnInfo->ulMinReplySize;

  for ( ulCnt = 0; ulCnt < pShmConnInfo->ulPacketCnt; ulCnt++ )
    pConnParam->pCommPacketList[ulCnt] = pShmConnInfo->pCommPacketList[ulCnt];

  DBGOUT;
  return ( SQLOK );
  }

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

#if defined(KERNEL)
  static ULONG sql33c_eval_xserv_conn_reply( PSHM_CONNECT_INFO_REC pShmConnInfo,
                                             PCONNECT_PARAM_REC    pConnParam,
                                             ERRORTEXT             pErrText )
   {
   #undef  MF__
   #define MF__ MOD__"sql33c_eval_xserv_conn_reply"
   ULONG                           ulCnt;
   PCOMM_SEG_HEADER_REC            pCSHeader;
   PCOMM_SEG_OFFSET_REC            pCSOffsetList;
   ULONG                           ulMyHeaderSize;
   ULONG                           ulPeerHeaderSize;

   DBGIN;

   pCSHeader     = pShmConnInfo->pCSHeader;
   pCSOffsetList = (PCOMM_SEG_OFFSET_REC) ((PCHAR)pCSHeader +
                                                 COMM_SEG_HEADER_SIZE);

   ulMyHeaderSize   = pShmConnInfo->ulPacketSize -
                      pShmConnInfo->ulMaxDataLen;
   ulPeerHeaderSize = pCSHeader->ulPacketSize -
                      pCSHeader->ulMaxDataLen;

   if (( ulMyHeaderSize             > ulPeerHeaderSize )         ||
       ( pShmConnInfo->ulPacketSize < pCSHeader->ulPacketSize )  ||
       ( pCSHeader->ulMaxDataLen    < (pCSHeader->ulMinReplySize * 2) ))
     {
     sql46c_build_error_string( pErrText, ERRMSG_INVALID_REPL_PACKET_SIZE, 0 );

     MSGD (( ERR_INVALID_REPL_PACKET_SIZE, pShmConnInfo->ulPacketSize,
             pShmConnInfo->pCSHeader->ulPacketSize, ulMyHeaderSize,
             ulPeerHeaderSize, pShmConnInfo->pCSHeader->ulMinReplySize ));
     DBGOUT;
     return ( SQLNOTOK );
     }

   pShmConnInfo->ulMinReplySize  = pCSHeader->ulMinReplySize;
   pShmConnInfo->ulPacketSize    = pCSHeader->ulPacketSize;
   pShmConnInfo->ulMaxDataLen    = pCSHeader->ulMaxDataLen;
   pShmConnInfo->ulServerRef     = pCSHeader->ulServerRef;


   for ( ulCnt = 0; ulCnt < pShmConnInfo->ulPacketCnt; ulCnt++ )
     {
     pShmConnInfo->pCommPacketList[ulCnt]= (PCOMM_PACKET_REC)((PCHAR)pCSHeader +
                                           pCSOffsetList->ulOffset[ulCnt]);
     }

   // --- set output parameter
   //
   pConnParam->ulServerRef       = pShmConnInfo->ulServerRef;
   pConnParam->ulPacketSize      = pShmConnInfo->ulPacketSize;
   pConnParam->ulMaxDataLen      = pShmConnInfo->ulMaxDataLen;
   pConnParam->ulMinReplySize    = pShmConnInfo->ulMinReplySize;

   for ( ulCnt = 0; ulCnt < pShmConnInfo->ulPacketCnt; ulCnt++ )
     pConnParam->pCommPacketList[ulCnt] = pShmConnInfo->pCommPacketList[ulCnt];

   DBGOUT;
   return ( SQLOK );
   }
#endif

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

static VOID sql33c_connect_cleanup ( PSHM_CONNECT_INFO_REC    pShmConnInfo )
  {
  #undef  MF__
  #define MF__ MOD__"sql33c_connect_cleanup"

  DBGPAS;

  #if !defined (KERNEL)
   if ( pShmConnInfo->hevClientSem  != (HEV)INVALID_HANDLE_VALUE )
     sql33c_close_client_sem( pShmConnInfo->hevClientSem, NULL );
  #endif

  if ( pShmConnInfo->hQueMailSlot != INVALID_HANDLE_VALUE );
    sql33c_close_queue_mailslot( pShmConnInfo->hQueMailSlot, NULL );

  if ( pShmConnInfo->hevServerSem != (HEV)INVALID_HANDLE_VALUE )
    sql33c_close_server_sem( pShmConnInfo->hevServerSem, NULL );

  if ( pShmConnInfo->pFCS != NULL )
    sql33c_free_flag_comm_seg( pShmConnInfo->hFCS, pShmConnInfo->pFCS, NULL );

  if ( pShmConnInfo->pCSHeader != NULL )
    sql33c_free_comm_seg( pShmConnInfo->hCS, pShmConnInfo->pCSHeader, NULL );

  // --- initialize the handles and pointers of connect information record
  sql33c_init_conn_info ( pShmConnInfo, NULL );

  return;
  }

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

static VOID sql33c_init_conn_info ( PSHM_CONNECT_INFO_REC pShmConnInfo,
                                    PCONNECT_PARAM_REC    pConnParam )
  {
  #undef  MF__
  #define MF__ MOD__"sql33c_init_conn_info"

  DBGPAS;

  pShmConnInfo->hQueMailSlot = INVALID_HANDLE_VALUE;
  pShmConnInfo->hevClientSem = (HEV)INVALID_HANDLE_VALUE;
  pShmConnInfo->hevServerSem = (HEV)INVALID_HANDLE_VALUE;
  pShmConnInfo->hCS          = INVALID_HANDLE_VALUE;
  pShmConnInfo->pCSHeader    = NULL;
  pShmConnInfo->hFCS         = INVALID_HANDLE_VALUE;
  pShmConnInfo->pFCS         = NULL;

  if ( pConnParam == NULL )
    {
    pShmConnInfo->pidClientPID    = (PID)UNDEF;
    pShmConnInfo->szClientNode[0] = '\0';
    pShmConnInfo->szServerDB[0]   = '\0';
    pShmConnInfo->ulServerRef     = (ULONG)UNDEF;
    pShmConnInfo->ulClientRef     = (ULONG)UNDEF;
    pShmConnInfo->ulServiceType   = (ULONG)UNDEF;

    pShmConnInfo->ulCurrentPacket = (ULONG)UNDEF;
    pShmConnInfo->ulCmdDataLen    = (ULONG)UNDEF;
    pShmConnInfo->ulPacketCnt     = 0;

    pShmConnInfo->ulPacketSize    = 0;
    pShmConnInfo->ulMaxDataLen    = 0;
    pShmConnInfo->ulMinReplySize  = (ULONG)UNDEF;
    pShmConnInfo->ulCommFlagNo    = (ULONG)UNDEF;
    }
  else
    {
    pShmConnInfo->pidClientPID    = pConnParam->pidClientPID;
    pShmConnInfo->ulServerRef     = (ULONG)UNDEF;
    pShmConnInfo->ulClientRef     = pConnParam->ulClientRef;
    pShmConnInfo->ulServiceType   = pConnParam->ulServiceType;

    pShmConnInfo->ulCurrentPacket = (ULONG)UNDEF;
    pShmConnInfo->ulCmdDataLen    = (ULONG)UNDEF;
    pShmConnInfo->ulPacketCnt     = pConnParam->ulPacketCnt;

    pShmConnInfo->ulPacketSize    = pConnParam->ulPacketSize;
    pShmConnInfo->ulMaxDataLen    = pConnParam->ulMaxDataLen;
    pShmConnInfo->ulMinReplySize  = (ULONG)UNDEF;

    pShmConnInfo->ulCommFlagNo    = pConnParam->ulCommFlagNo;

    if ( pConnParam->pszClientNode )
      strcpy ( pShmConnInfo->szClientNode, pConnParam->pszClientNode );
    else
      pShmConnInfo->szClientNode[0] = '\0';

    if ( pConnParam->pszServerNode )
      strcpy ( pShmConnInfo->szServerNode, pConnParam->pszServerNode );
    else
      pShmConnInfo->szServerNode[0] = '\0';

    strcpy ( pShmConnInfo->szServerDB,   pConnParam->pszServerDB );
    strupr ( pShmConnInfo->szServerDB );
    }

  return;
  }

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