/*static char *SCCSID = "@(#)logcal32.c	6.7 91/11/03";*/
/****************************************************************************/
/*                                                                          */
/*                       IBM/Microsoft Confidential                         */
/*                                                                          */
/*                 Copyright (c) IBM Corporation  1987, 1990                */
/*                 Copyright (c) Microsoft Corp.  1987, 1990                */
/*                           All Rights Reserved                            */
/*                                                                          */
/****************************************************************************/
/************************** START OF SPECIFICATIONS **********************
*
*   SOURCE FILE NAME:  LogCalls.c
*
*   DESCRIPTIVE NAME:  LogCalls Dynalink Library
*
*   STATUS: RELEASE 1 LEVEL 0
*
*   FUNCTION: Provides a two way communication between the logging
*             facility and sub-systems.
*
*   ENTRY POINTS:
*                 LogOpen
*                 LogClose
*                 LogAddEntries
*                 LogGetEntries
*                 LogSetState
*                 LogSetName
*                 LogQueryState
*
*   INTERNAL REFERENCES:
*      DATA: NONE
*
*   EXTERNAL REFERENCES:
*      ROUTINES:
*                       DOS32CLOSE
*                       DOS32OPEN
*                       DOS32DEVIOCTL
*                       DOS32GETINFOBLOCKS              dcr 1393
*                       DOS32QUERYMODULENAME
*
*
**************************** END OF SPECIFICATIONS **********************/

#define LOGDAEM           /* needed to get LOGDAEM error messages utilmd31.h */
#define INCL_DOSERRORS
#define INCL_DOSNMPIPES
#define INCL_DOSMODULEMGR
#define INCL_DOSSEMAPHORES
#define INCL_DOS
#define INCL_DOSEXCEPTIONS   /* needed for using exception handler     */
#define INCL_DOSPROCESS      /* needed for using thread information    */
#ifndef INCL_OS2STD
#define INCL_OS2STD                    /* need to include defs for NULL, etc */
#endif

/*
 * The following defines create the correct names for Dos* while still
 * allowing use of definitions from os2.h
 */

#define DosClose            DOS32CLOSE
#define DosOpen             DOS32OPEN
#define DosDevIOCtl         DOS32DEVIOCTL
#define DosGetInfoBlocks    DOS32GETINFOBLOCKS
#define DosQueryModuleName  DOS32QUERYMODULENAME

#include <os2.h>
#include <sysbits.h>
#include <bseerr.h>
#define LOGDAEM           /* needed to get LOGDAEM error messages utilmd31.h */
#include <utilmids.h>
#include <stddef.h>       /* needed for size_t  */


/**********************************************/
/*    Log Entry Record Header for 2.X         */
/**********************************************/

typedef struct LogRecord
{
  USHORT   len ;            /* this record length(includes len field)        */
  USHORT   rec_id ;         /* record id                                     */
  ULONG    status ;         /* record status bits(see LF_BIT_)               */
  UCHAR    qualifier[4] ;   /* qualifier tag                                 */
  ULONG    reserved ;
  ULONG    time ;           /* hours minutes seconds hundreds                */
  ULONG    date ;           /* day month (USHORT)year                        */
  UCHAR    data[1] ;        /* begin of variable data that includes:         */
                            /*     Originator(256 bytes if LF_BIT_ORIGIN_256)*/
                            /*               else 8 bytes long               */
                            /*     Processname(260 bytes) only if status     */
                            /*                 BIT_PROCESSNAME set           */
                            /*     FormatDLLName(12 bytes)                   */
                            /*     Variable data                             */
} LOGRECORD ;
typedef LOGRECORD  *PLOGREC ;

/************************************************/
/* LogRecord status bits                        */
/************************************************/
#define LF_BIT_PROCNAME     0x0001L
#define LF_BIT_ORIGIN_256   0x0002L
#define LF_BIT_DATETIME     0x0004L
#define LF_BIT_SUSPEND      0x0008L
#define LF_BIT_RESUME       0x0010L
#define LF_BIT_REDIRECT     0x0020L
#define LF_BIT_GETSTATUS    0x0040L
#define LF_BIT_REGISTER     0x0080L

/************************************************************/
/* Minimum buffer size for LogGetEntries is 4K              */
/* The first two WORDs in the buffer are revision and count */
/* Therefor the Max size of a log record is 4K - 4          */
/************************************************************/
#define LF_MAX_REC_SIZE     4092

/************************************************/
/* Format of buffer sent to LogAddEntries       */
/************************************************/
typedef struct LogEntryRec
{
  USHORT    version ;                /* this version is 1                    */
  USHORT    count   ;                /* number of log records in this buffer */
  LOGRECORD logrec  ;                /* repeated count times                 */
} LOGENTRYREC ;
typedef LOGENTRYREC  *PLOGENTRYREC ;


/*******************************************************/
/* Exception routine invoked when an exception occurrs */
/* in certain APIs which set an exception handler.     */
/*******************************************************/
ULONG _cdecl ExceptRoutine(PEXCEPTIONREPORTRECORD,
                           PEXCEPTIONREGISTRATIONRECORD,
                           PCONTEXTRECORD,
                           PVOID);



/***************************************************************************/
/* Structure passed as a pointer to DosSetException Handler.  This         */
/* pointer will be available in the exception routine.  Thus the exception */
/* routine will be able to access the extra fields which will be used to   */
/* to restore the environment of the application and return to it.         */
/***************************************************************************/
typedef struct  SysERegRec {
   PEXCEPTIONREGISTRATIONRECORD pLink;
   ULONG (_cdecl *pSysEH)(PEXCEPTIONREPORTRECORD,
                          PEXCEPTIONREGISTRATIONRECORD,
                          PCONTEXTRECORD,
                          PVOID);
   ULONG pRetEIP;
   PEXCEPTIONREGISTRATIONRECORD pUserEH;
   ULONG ulcParms;
} SYSEREGREC;
typedef SYSEREGREC *PSYSEREGREC;

/***************************************************/
/* Logging Defines                                 */
/***************************************************/
#define ERRLOG_SERVICE        1L
#define ERRLOG_VERSION        1
#define LF_STATUS_SUSPENDED   0x0000
#define LF_STATUS_ACTIVE      0x0001
#define FUNCTION_NOT_SUPPORTED 0x1641

/**********************************************/
/* Type of entries to return to LogGetEntries */
/**********************************************/
#define LF_TYPE_ALL           1L
#define LF_TYPE_DD_ONLY       2L

/**********************************************/
/* LogSetState action codes                   */
/**********************************************/
#define LF_SUSPEND            0L
#define LF_RESUME             1L


/**********************************************/
/* Defines for IOCTLs for LOG$ device driver  */
/**********************************************/
#define IOCTL_LOGGING             0x000C
#define LOGGING_SUSPEND           0x0040
#define LOGGING_SUSPEND_RESPONSE  0x0041
#define LOGGING_RESUME            0x0042
#define LOGGING_RESUME_RESPONSE   0x0043
#define LOGGING_ADDENTRIES        0x0044
#define LOGGING_REDIRECTLOGFILE   0x0045
#define LOGGING_REDIRECTRESPONSE  0x0046
#define LOGGING_QRYSTATERESPONSE  0x0047
#define LOGGING_REQUESTACCESS     0x0048
#define LOGGING_RELEASEACCESS     0x0049
#define LOGGING_SETTIMEOUT        0x004A
#define LOGGING_REGISTER          0x004B
#define LOGGING_REGISTERRESPONSE  0x004C
#define LOGGING_DAEMON_INIT       0x004D
#define LOGGING_GETENTRIES        0x0060
#define LOGGING_QUERYSTATE        0x0061


/**  LOG$ DD defined Error codes, to be returned by DosDevIOCtl
 **       after masking off high byte
 **/
#define LOGDD_ERR_BASE                  0xFE00
#define LOGDD_ERR_MASK                  0x00FF

#define LOGDD_INVALID_PARAMETER         0x0001
#define LOGDD_INVALID_RECORD_FORMAT     0x0002
#define LOGDD_INVALID_VERSION           0x0003
#define LOGDD_INVALID_BUF_INDEX         0x0004
#define LOGDD_INVALID_LOGTYPE           0x0005
#define LOGDD_GENERAL_FAILURE           0x0006
#define LOGDD_DAEMON_NOT_INIT           0x0007
#define LOGDD_DAEMON_ALREADY_INIT       0x0008
#define LOGDD_LF_SUSPENDED              0x0009
#define LOGDD_TIMEOUT                   0x000A
#define LOGDD_BUF_FULL                  0x000B
#define LOGDD_BUF_TOO_SMALL             0x000C
/*
 * The following codes are returned by the LOGDAEM for
 *   resume and redirect logging calls(see \drv6\src\cmd\logdaem\logdaem.c)
 *   NOTE: if unable to resume to remote file but able to use local file
 *           LOGDD_REMOTE_FAIL_USING_LOCAL is always returned.
 *           The LOGDAEM will not give specific error code why logging
 *           could not be resumed to remote file.
 */
#define LOGDD_REDIRECT_PATH_NOT_FOUND   0x0010
#define LOGDD_REDIRECT_ACCESS_DENIED    0x0011
#define LOGDD_REDIRECT_BAD_FILE_HEADER  0x0012
#define LOGDD_REDIRECT_INVALID_DRIVE    0x0013
#define LOGDD_REDIRECT_DRIVE_NOT_READY  0x0014
#define LOGDD_REMOTE_FAIL_USING_LOCAL   0x0015




/************************** START OF SPECIFICATIONS **********************
*
*   SUBROUTINE NAME:   LogOpen
*
*   DESCRIPTIVE NAME:  Open logging device driver LOG$
*
*   FUNCTION: The LogOpen function provides the interface for
*             subsystems to obtain a handle to the logging device driver.
*             This handle is needed on subsequent LogXXXX calls.
*
*   ENTRY POINT:  LogOpen
*
*   PARAMETERS: PUSH@  HANDLE phf         ; address to put file handle
*
*       Where:
*
*          phf :      is the address to place the file handle for the
*                     logging device driver
*
*
*   EXIT-NORMAL:    AX = 0       No error.
*
*   EXIT-ERROR:     AX = Error Code
*
*           Possible errors:  ERROR_LF_NOT_AVAIL - if logging is not
*                                      enabled(no DEVICE=LOG.SYS in config.sys)
*
*   EFFECTS:   none
*
*   INTERNAL REFERENCES: none
*
*   EXTERNAL REFERENCES:
*      ROUTINES:        DosOpen
*
**************************** END OF SPECIFICATIONS **********************/
APIRET APIENTRY LOGOPEN( PHFILE phf )
{
  ULONG            rc ;         /* Return code */
  ULONG            action ;
  ULONG            rcc;         /* Return code */
  PTIB             pTib;        /* Thread information block */
  PPIB             pPib;        /* Process information block */
  SYSEREGREC       RegRec;
  ULONG            E_S_P;       /* Stack pointer */
  size_t           param_size;  /* Used to know the bytes of the parameters */

_asm {
        push eax
        mov  eax,ebp            /* Stack pointer when entering this API */
        mov  E_S_P,eax
        pop  eax
     }

     rcc = DosGetInfoBlocks(&pTib, &pPib);  /* Need Tib */
     if (rcc == 0)                      /* Continue to set Exception Handler */
        {
         param_size = sizeof(phf);             /* Bytes of the parameter */
         RegRec.ulcParms = (ULONG) param_size;
         RegRec.pRetEIP = E_S_P;
         RegRec.pUserEH = (PEXCEPTIONREGISTRATIONRECORD)pTib->tib_pexchain;
         RegRec.pLink = NULL;
         RegRec.pSysEH = ExceptRoutine;
         rcc = DosSetExceptionHandler( (PEXCEPTIONREGISTRATIONRECORD) &RegRec) ;
        }

     rc = (ULONG)DosOpen  (
                  (PSZ)"LOG$"       ,        /* file name        */
                  (PHFILE)phf       ,        /* file handle      */
                  (PULONG)&action   ,        /* action taken     */
                  0L           ,             /* file size        */
                  0L           ,             /* file attribute   */
                  OF_OPEN_FILE ,
                  ( OM_DENY_NONE | OM_READ_WRITE ),
                  (PEAOP)0     );            /* reserved         */

     if (rcc == 0)  /* If all went well above to set the exception handler */
        DosUnsetExceptionHandler( (PEXCEPTIONREGISTRATIONRECORD) &RegRec) ;

     if (rc)
       rc = ERROR_LF_NOT_AVAIL ;
     return rc ;
}


/************************** START OF SPECIFICATIONS **********************
*
*   SUBROUTINE NAME:   LogClose
*
*   DESCRIPTIVE NAME:  Close logging device driver LOG$
*
*   FUNCTION: The LogClose function provides the interface for
*             subsystems to close their current connection to the
*             logging device driver LOG$
*
*   ENTRY POINT:  LogClose
*
*   PARAMETERS: PUSH   HANDLE hf          ; file handle from LogOpen
*
*       Where:
*
*          hf :       is the file handle returned from LogOpen
*
*
*   EXIT-NORMAL:    AX = 0       No error.
*
*   EXIT-ERROR:     AX = Error Code
*
*           Possible errors:  ERROR_INVALID_HANDLE
*
*   EFFECTS:   none
*
*   INTERNAL REFERENCES: none
*
*   EXTERNAL REFERENCES:
*      ROUTINES:        DosClose
*
**************************** END OF SPECIFICATIONS **********************/

APIRET APIENTRY LOGCLOSE( HFILE hf )
{
  USHORT  rc ;

  rc = (USHORT)DosClose  ( hf ) ;
  return rc ;
}


/************************** START OF SPECIFICATIONS **********************
*
*   SUBROUTINE NAME:   LogAddEntries
*
*   DESCRIPTIVE NAME:  AddEntries to log file
*
*   FUNCTION: The LogAddEntries function provides the interface for
*             subsystems to add entries to the logging system.
*
*   ENTRY POINT:  LogAddEntries
*
*   PARAMETERS: PUSH   HANDLE hf          ; file handle from LogOpen
*               PUSH   ULONG  ulService   ; class of logging:
*                                         ;   0 - Reserved
*                                         ;   1 - Error Logging
*                                         ;   2-FFFFFFFF - Reserved
*               PUSH@  OTHER  pLogEntries ; buffer containing entries to log
*                                         ;   format is:
*                                         ;      WORD - revision number(1)
*                                         ;      WORD - # log entry packets
*                                         ;      OTHER- begin of 1st packet
*
*       Where:
*
*          hf :       is the file handle returned from LogOpen
*          ulService: is the class of logging requested(1 = Error Logging)
*          pLogEntries: points to buffer containing:
*                          WORD - revision(1 is current revision)
*                          WORD - # log records in this buffer
*                          OTHER- beginning of 1st record to log
*
*
*   EXIT-NORMAL:    AX = 0       No error.
*
*   EXIT-ERROR:     AX = Error Code
*
*           Possible errors:  ERROR_INVALID_HANDLE
*                             ERROR_LF_SUSPENDED
*                             ERROR_LF_INVALID_SERVICE
*                             ERROR_LF_INVALID_RECORD
*                             ERROR_LF_BUFFER_FULL
*                             ERROR_LF_GENERAL_FAILURE
*
*   EFFECTS:   none
*
*   INTERNAL REFERENCES: none
*
*   EXTERNAL REFERENCES:
*      ROUTINES:        DosDevIOCtl
*                       DosGetInfoBlocks
*                       DosQueryModuleName
*
**************************** END OF SPECIFICATIONS **********************/

APIRET APIENTRY LOGADDENTRIES( HFILE hf, ULONG ulService, PVOID pLogEntries )
{
  ULONG            rc ;
  USHORT           count ;            /* # packets to log */
  USHORT           len   ;
  USHORT           originlen ;
  PLOGENTRYREC     pLogEntryRec ;
  PLOGREC          pLogRec ;
  PTIB             ptib ;             /* used to get processname */
  PPIB             ppib ;             /* used to get processname */
  ULONG            Parmlist[2] ;
  char _far16      *pBuf ;         /* converts pointers from linear to 16:16 */
  ULONG            rcc;            /* Return code */
  SYSEREGREC       RegRec;
  ULONG            E_S_P;
  size_t           param_size;     /* size of the parameters in bytes */


_asm {
        push eax
        mov  eax,ebp               /* Stack pointer when entering this API */
        mov  E_S_P,eax
        pop  eax
     }

     rcc = DosGetInfoBlocks(&ptib, &ppib);  /* Need Tib */
     if (rcc == 0)                      /* Continue to set Exception Handler */
        {
         param_size = sizeof(hf);
         param_size += sizeof(ulService);
         param_size += sizeof(pLogEntries);
         RegRec.ulcParms = (ULONG) param_size;
         RegRec.pRetEIP = E_S_P;
         RegRec.pUserEH = (PEXCEPTIONREGISTRATIONRECORD)ptib->tib_pexchain;
         RegRec.pLink = NULL;
         RegRec.pSysEH = ExceptRoutine;
         rcc = DosSetExceptionHandler( (PEXCEPTIONREGISTRATIONRECORD) &RegRec) ;
        }


  if (ulService != ERRLOG_SERVICE)
    rc = ERROR_LF_INVALID_SERVICE ;
  else
  {
    rc = 0 ;
    pLogEntryRec = (PLOGENTRYREC)pLogEntries ;
    if (pLogEntryRec->version != ERRLOG_VERSION)
      rc = ERROR_LF_INVALID_RECORD ;
    count = pLogEntryRec->count ;
    pLogRec = &pLogEntryRec->logrec ;
    while ( (count--) && (rc == 0) )
    {
      len = pLogRec->len ;
      if (pLogRec->status & LF_BIT_PROCNAME)
      {
        if (pLogRec->status & LF_BIT_ORIGIN_256)
          originlen = 256 ;
        else
          originlen = 8 ;
        if (len < (USHORT)(sizeof(LOGRECORD) + originlen + 259) )
          rc = ERROR_LF_INVALID_RECORD ;
        else
        {
         /* Get application's process name. If unable, still log the record */
           if ( !(DosGetInfoBlocks(&ptib, &ppib)) )
             DosQueryModuleName(ppib->pib_hmte, 260L,
                                (PCHAR)&(pLogRec->data+originlen));
        }
      }
      /**
       ** Check next record
       ** Note: all records are DWORD aligned(%4)
       **/
      pLogRec = (PLOGREC)((char  *)pLogRec + len + (len % 4) ) ;
    }

    if (!rc)
    {
      Parmlist[0] = ERRLOG_SERVICE;                    /* Logging class   */
      pBuf = (char _far16 *)pLogEntries ;     /* convert to 16:16 pointer */
      Parmlist[1] = (ULONG)pBuf ;                      /* LogEntry buffer */
      rc =  (ULONG)  DosDevIOCtl(
                     (HFILE)hf,                      /* DD filehandle   */
                     (ULONG)IOCTL_LOGGING,           /* category        */
                     (ULONG)LOGGING_ADDENTRIES ,     /* function code   */
                     (PVOID)&Parmlist ,              /* Parmlist        */
                     8,                              /* Parmlist Length */
                     NULL,                           /* Ptr to reserved */
                     NULL,                           /* Data ptr        */
                     0,                              /* Length of Data  */
                     0);                             /* Must be zero    */

      if (rc > LOGDD_ERR_BASE)
      {
        /**
         ** Must convert IOCtl return code
         ** because LOG$ device driver can only return one byte of
         ** error code
         **/
        switch (rc & LOGDD_ERR_MASK)
        {
          case LOGDD_INVALID_RECORD_FORMAT :
               rc = ERROR_LF_INVALID_RECORD ;
               break;
          case LOGDD_GENERAL_FAILURE :
               rc = ERROR_LF_GENERAL_FAILURE ;
               break;
          case LOGDD_DAEMON_NOT_INIT :
               rc = ERROR_LF_NOT_AVAIL ;
               break;
          case LOGDD_LF_SUSPENDED :
               rc = ERROR_LF_SUSPENDED ;
               break;
          case LOGDD_BUF_FULL :
               rc = ERROR_LF_BUFFER_FULL ;
               break;
          case LOGDD_BUF_TOO_SMALL :
               rc = ERROR_LF_BUF_TOO_SMALL ;
               break;
          default:
               rc = ERROR_LF_GENERAL_FAILURE ;
               break;
        }
      }
    }
  }

  if (rcc == 0)  /* If all went well above to set the exception handler */
     DosUnsetExceptionHandler( (PEXCEPTIONREGISTRATIONRECORD) &RegRec) ;

  return rc ;
}


/************************** START OF SPECIFICATIONS **********************
*
*   SUBROUTINE NAME:   LogGetEntries
*
*   DESCRIPTIVE NAME:  Get log entries from logging device driver buffer
*
*   FUNCTION: The LogGetEntries function provides the interface for
*             the logdaemon to get entries from the log device driver
*             that were logged via LogAddEntries
*
*   ENTRY POINT:  LogGetEntries
*
*   PARAMETERS: PUSH   HANDLE hf          ; file handle from LogOpen
*               PUSH   ULONG  ulService   ; class of logging:
*                                         ;   0 - Reserved
*                                         ;   1 - Error Logging
*                                         ;   2-FFFFFFFF - Reserved
*               PUSH   ULONG  ulType      ; type of buffer to return:
*                                         ;   0 - Reserved
*                                         ;   1 - buffer containing all logged
*                                         ;       entries.
*                                         ;   2 - buffer containing only log
*                                         ;       records added by device
*                                         ;       drivers
*               PUSH@  OTHER  pLogBuffer  ; address of buffer to return entries
*                                         ;   format is:
*                                         ;      WORD - revision number(1)
*                                         ;      WORD - # log entry packets
*                                         ;      OTHER- begin of 1st record
*                                         ;   NOTE: if buffer too small, 1st
*                                         ;      DWORD of buffer will have
*                                         ;      needed length.
*               PUSH   ULONG  ulBufferLen ; length(bytes) of LogBuffer
*
*       Where:
*
*          hf :       is the file handle returned from LogOpen
*          ulService: is the class of logging requested(1 = Error Logging)
*          ulType:    is type of buffer entries to return(1 = all,
*                        2 = only those logged from device drivers)
*          pLogBuffer: points to buffer that will contain on return:
*                          WORD - revision(1 is current revision)
*                          WORD - # log records in this buffer
*                          OTHER- beginning of 1st record in buffer
*          ulBufferLen: length(in bytes) of buffer given.
*
*
*   EXIT-NORMAL:    AX = 0       No error.
*
*   EXIT-ERROR:     AX = Error Code
*
*           Possible errors:  ERROR_INVALID_HANDLE
*                             ERROR_LF_BUF_TOO_SMALL
*                             ERROR_LF_INVALID_SERVICE
*                             ERROR_LF_GENERAL_FAILURE
*                             ERROR_LF_INVALID_FUNCTION
*   EFFECTS:   none
*
*   INTERNAL REFERENCES: none
*
*   EXTERNAL REFERENCES:
*      ROUTINES:        DosDevIOCtl
*
**************************** END OF SPECIFICATIONS **********************/

APIRET APIENTRY LOGGETENTRIES( HFILE hf, ULONG ulService, ULONG ulType,
                               PVOID pLogBuffer, ULONG ulBufferLen )
{
  ULONG  rc ;
  rc = FUNCTION_NOT_SUPPORTED ;

  return rc ;
}


/************************** START OF SPECIFICATIONS **********************
*
*   SUBROUTINE NAME:   LogSetState
*
*   DESCRIPTIVE NAME:  Set the state of the logging facility
*
*   FUNCTION: The LogSetState function provides the interface for
*             Syslog to suspend or resume logging
*
*   ENTRY POINT:  LogSetState
*
*   PARAMETERS: PUSH   HANDLE hf          ; file handle from LogOpen
*               PUSH   ULONG  ulService   ; class of logging:
*                                         ;   0 - Reserved
*                                         ;   1 - Error Logging
*                                         ;   2-FFFFFFFF - Reserved
*               PUSH   ULONG  ulAction    ; action to take:
*                                         ;   0 - suspend logging
*                                         ;   1 - resume logging
*
*       Where:
*
*          hf :       is the file handle returned from LogOpen
*          ulService: is the class of logging requested(1 = Error Logging)
*          ulAction:  is action to take.  0 - suspend, 1 - resume logging
*
*   EXIT-NORMAL:    AX = 0       No error.
*
*   EXIT-ERROR:     AX = Error Code
*
*           Possible errors:  ERROR_INVALID_HANDLE
*                             ERROR_LF_INVALID_FUNCTION
*                             ERROR_LF_INVALID_SERVICE
*                             ERROR_LF_GENERAL_FAILURE
*                             ERROR_LF_NOT_AVAIL
*                             ERROR_LF_BUFFER_FULL
*                             ERROR_LF_TIMEOUT
*
*   EFFECTS:   none
*
*   INTERNAL REFERENCES: none
*
*   EXTERNAL REFERENCES:
*      ROUTINES:        DosDevIOCtl
*
**************************** END OF SPECIFICATIONS **********************/

APIRET APIENTRY LOGSETSTATE( HFILE hf, ULONG ulService, ULONG ulAction )
{
  ULONG   rc ;

  rc = FUNCTION_NOT_SUPPORTED;

  return rc ;
}


/************************** START OF SPECIFICATIONS **********************
*
*   SUBROUTINE NAME:   LogSetName
*
*   DESCRIPTIVE NAME:  Set the state of the logging facility
*
*   FUNCTION: The LogSetName function provides the interface for
*             Syslog to change the file that the logdaemon writes
*             log records to.
*
*   ENTRY POINT:  LogSetName
*
*   PARAMETERS: PUSH   HANDLE hf          ; file handle from LogOpen
*               PUSH   ULONG  ulService   ; class of logging:
*                                         ;   0 - Reserved
*                                         ;   1 - Error Logging
*                                         ;   2-FFFFFFFF - Reserved
*               PUSH@  CHAR   pszFileName ; new filename to log to
*               PUSH   ULONG  ulFileSize  ; size of new logfile in KB
*
*       Where:
*
*          hf :       is the file handle returned from LogOpen
*          ulService: is the class of logging requested(1 = Error Logging)
*          pszFileName: is the fully qualified path to new filename to copy
*                     log records into.
*          ulFileSize: is the initial size of the file(in KB).  If the file
*                     already exists, the maximum size of the file will be the
*                     greatest of ulFileSize and the current file's size(KB).
*
*   EXIT-NORMAL:    AX = 0       No error.
*
*   EXIT-ERROR:     AX = Error Code
*
*           Possible errors:  ERROR_INVALID_HANDLE
*                             ERROR_LF_INVALID_SERVICE
*                             ERROR_LF_GENERAL_FAILURE
*                             ERROR_LF_NOT_AVAIL
*                             ERROR_LF_BUFFER_FULL
*                             ERROR_LF_REDIRECT_FAILURE
*                             ERROR_LF_TIMEOUT
*
*   EFFECTS:   none
*
*   INTERNAL REFERENCES: none
*
*   EXTERNAL REFERENCES:
*      ROUTINES:        DosDevIOCtl
*
**************************** END OF SPECIFICATIONS **********************/

APIRET APIENTRY LOGSETNAME( HFILE hf, ULONG ulService, PSZ pszFileName,
                            ULONG ulFileSize )
{
  ULONG  rc ;

  rc = FUNCTION_NOT_SUPPORTED;

  return rc ;
}


/************************** START OF SPECIFICATIONS **********************
*
*   SUBROUTINE NAME:   LogQueryState
*
*   DESCRIPTIVE NAME:  Queries the state of the logging facility
*
*   FUNCTION: The LogQueryState function provides the interface for
*             Syslog to determine the current state of logging
*
*   ENTRY POINT:  LogQueryState
*
*   PARAMETERS: PUSH   HANDLE hf          ; file handle from LogOpen
*               PUSH   ULONG  ulService   ; class of logging:
*                                         ;   0 - Reserved
*                                         ;   1 - Error Logging
*                                         ;   2-FFFFFFFF - Reserved
*               PUSH@  PVOID  pBuffer     ; buffer to contain LOGSTATE struct
*
*       Where:
*
*          hf :       is the file handle returned from LogOpen
*          ulService: is the class of logging requested(1 = Error Logging)
*          pBuffer:   is address of buffer that will get LOGSTATE structure
*                     copied into it.
*
*   EXIT-NORMAL:    AX = 0       No error.
*
*   EXIT-ERROR:     AX = Error Code
*
*           Possible errors:  ERROR_INVALID_HANDLE
*                             ERROR_LF_INVALID_SERVICE
*                             ERROR_LF_GENERAL_FAILURE
*                             ERROR_LF_NOT_AVAIL
*                             ERROR_LF_BUFFER_FULL
*                             ERROR_LF_TIMEOUT
*
*
*   EFFECTS:   none
*
*   INTERNAL REFERENCES: none
*
*   EXTERNAL REFERENCES:
*      ROUTINES:        DosDevIOCtl
*
**************************** END OF SPECIFICATIONS **********************/

APIRET APIENTRY LOGQUERYSTATE( HFILE hf, ULONG ulService, PVOID pBuffer )
{
  ULONG  rc ;

  rc = FUNCTION_NOT_SUPPORTED;


  return rc ;
}


/************************************************************************/
/* This is the function called if an exception occurs in an API where   */
/* an exception handler has been set                                    */
/************************************************************************/
ULONG _cdecl ExceptRoutine(PEXCEPTIONREPORTRECORD pReportRec ,
                           PEXCEPTIONREGISTRATIONRECORD pLocalXRR,
                           PCONTEXTRECORD context,
                           PVOID pVoid)
{
        ULONG        rcc;
        PTIB         pTib;
        PPIB         pPib;
        PSYSEREGREC  pLocalRR;
        ULONG        E_S_P;
        ULONG        params;

        if (pReportRec->ExceptionNum == XCPT_ACCESS_VIOLATION)
           {
           pLocalRR = (PSYSEREGREC) pLocalXRR;
           rcc = DosGetInfoBlocks(&pTib, &pPib);
           if (rcc == 0)
              {
              pTib->tib_pexchain=pLocalRR->pUserEH;  /* reset exception chain */
                                          /* to before DosSetExceptionHandler */

              E_S_P=pLocalRR->pRetEIP;  /* Reset stack pointer to what it was */
                                        /* when API was entered */

              params = pLocalRR->ulcParms;/* Number of bytes of the parameters */

              _asm
                 {
                 mov  ebx,params    ; number of bytes to remove from the stack
                 mov  eax,E_S_P     ; stack pointer
                 mov  esp,eax
                 pop  ebp           ; was pushed on when the API was called
                 pop  eax           ; return address
                 add  esp,ebx       ; get rid of parameters
                 push eax           ; return address
                 mov  eax,87        ; bad_parameters
                 ret
                 }
              }
           else
              return XCPT_CONTINUE_SEARCH;
           }
        else
           return XCPT_CONTINUE_SEARCH;


        return XCPT_CONTINUE_SEARCH;    /* should never get here */
}

/*******/
/* EOF */
/*******/
