.CM  SCRIPT , Version - 1.1 , last edited by peter
.ad 8
.bm 8
.fm 4
.bt $Copyright (c) 1992-2005 SAP AG-2002$$Page %$
.tm 12
.hm 6
.hs 3
.tt 1 $SQL$Project Distributed Database System$VMT90C$
.tt 2 $$$
.TT 3 $BurkhardD$TRACEOUTPUT FUNCTIONS$$1999-09-20$
***********************************************************
.nf

.nf

.nf

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

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

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

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


.fo


.fo
Module  : Traceoutput Functions
=========
.sp
Purpose :
.CM *-END-* purpose -------------------------------------
Define  :
#include "gmt90.h"
.CM *-END-* define --------------------------------------
Use     :
.CM *-END-* use -----------------------------------------
Synonym :
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  : BurkhardD
.sp
.cp 3
Created : 08-31-1993
.sp
.cp 3
Version : 08-31-1993
.sp
.cp 3
Release :      Date : 1999-09-20
Specification:
.CM *-END-* specification -------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Description:
Dieses Modul beinhaltet die Routinen fuer Traceausgaben aus C-Modulen
Durch den Aufruf des Macros M90TRACE werden Traceausgaben in einer
Datei erzeugt. Nur Module, die mit SLOW uebersetzt wurden koennen
Traceausgaben erzeugen.

Einschalten des TRACE Files geschieht unter UNIX mit der Environment-
variablen M90TRACE=<filename>.

Unter WINDOWS wird der Trace mit der Section [M90TRACE] und dem Eintrag
TRACE=Y eingeschaltet. Der Tracefilename kann zur Laufzeit ueber eine
Dialogbox gesetzt werden.

Die Traceausgaben erfolgen nach Verschachtelungstiefe der Procedureaufrufe.
Die Tracetiefe kann mit der Environmentvariable M90LEVEL=<nr> (UNIX) oder
TRACELVEL=<nr> (WINDOWS) gesetzt werden. Als Default is 1 eingestellt.

Verschiedene Traceaugaben sind moeglich.

    Drei MACROS sind im Defineteil spezifiziert.

    M90TRACE(type, name, ptr)
    M90TRACELEN(type, name, ptr, len)
    M90TRACEBUF(name,ptr,pos,len);

    M90TRACE ist das generelle Tracemacro mit dem sich folgende Varianten
    erzeugen lassen.

    Wobei der 1. Parameter immer den Type der Variablen angibt, die
    ausgeben werden soll. Der 2. Parameter ist ein String (Name der Variablen)
    und der 3. Parameter der Wert selber (Pointer) vom Typ des ersten
    Parameters.

1)  Aufrufhierachie (M90_TR_ENTRY, M90_TR_EXIT)
    Um den Eintritt (Austritt) in eine Funktion zu protokollieren uebergibt
    man im 1. Parameter M90_ENTRY (M90_EXIT) und im 2. den Namen der
    Funktion. Der dritte Parameter bleibt unberuecksichtigt.

2)  Numerische Werte ( M90_TR_WORD, M90_TR_DWORD, M90_TR_SFLOAT, ... )
    Zahlen lassen sich in verschiedenen Darstellungsformen ausgeben, wobei
    zwischen 'signed' und 'unsigned' und der Laenge in Bytes unterschieden
    wird.
    Die jeweilige Ausgabe bestimmt das Erste Zeichen im "M90_TR_*" Macro.

       "M90_TR_S*"     : Ausgabe eines Wertes mit Vorzeichen.
       "M90_TR_U*"     : Ausgabe eines Wertes ohne Vorzeichen.
       "M90_TR_.WORD" : Ausgabe eines zwei Byte langen Wertes.
       "M90_TR_.DWORD" : Ausgabe eines vier Byte langen Wertes.
	

3)  Floatingpoint Zahlen
    Werden mit "M90_TR_SFLOAT", "M90_TR_SDOUBLE" ausgegeben.

4)  Strings (M90_TR_STRING, M90_TR_BUFFER) und das Macro M90TRACEBUF
    Hiermit koennen ASCII un Binaere Zeichenketten ausgegeben werden.

       "M90_TR_STRING" : Gibt einen nullterminierten String aus.
	                 In Verbindung mit M90TRACELEN koennen auch
			 nicht nullterminiert Strings ausgegeben werden.
			 Hierbei ist die Laenge im vierten Parameter an-
			 zugeben.
	
       "M90_TR_BUFFER" : Gibt in Verbindung mit M90TRACELEN einen Buffer
	                 Decimal und Hexadecimal aus.
5)  Buffer (Macro M90TRACEBUF)			
    M90TRACEBUF ist eine Version von M90TRACE(M90_TR_BUF,...), die den Buffer
    ab der Anfangsposition (3. Parameter) bis zur Angegebenen Laenge (4. Parm.)
    ausgibt.

.CM *-END-* description ---------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.nf
.oc _/1
Structure:
.CM *-END-* structure -----------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.CM -lll-
Code    :
#ifndef DEBUG
#line 282 "vmt90c"
#endif

char *m90_tr_profentry = M90_TR_PROFENTRY;
char *m90_tr_appname = M90_TR_APPNAME;
int m90_tr_buffersize = 512;
int m90_buffered_trace = 0;
int m90_flush_after = 10000;
int m90_line_count = 0;
static  char mt90tracelevel [ 10 ];
static  char mt90tracefile [ 260 ];
static  char mt90buffer  [1024];
static  char mt90outbuf  [1024];
static  char mt90hexlit [1024];
static  char mt90literal [1024];
static int mt90level = 0;
#ifdef WIN32
static OFSTRUCT mt90OfStruct;
#include <windows.h>
HINSTANCE m90s_hModule;
#endif


int m90_trace_status = 88;
int m90maxlevel = 1;

void mt90TraceOutPut(int * file_handle, char *szBuffer);

void m90ctrac( unsigned short int type, char *name,
void *ptr, long int len, long int pos)
{
  static int lazy_exit = 0;
  static char * level_ptr = NULL;
  static char * parm_ptr;
  char cpos  [ 20 ];
  char hchar  [ 20 ];
  char cchar  [ 20 ];
  char dchar  [ 20 ];
  char chr;
  int  noprint = 1;

  unsigned char uchar;
  unsigned short int uword;
  short int sword;
  unsigned long dword;
  long int sdword;
  char *p;
  long int i;
#ifndef WIN32
  static FILE * file_ptr;
#else
  static int file_handle;
#endif
#ifndef WIN32
  if (m90_trace_status == 88) {
    m90_trace_status = 1;
    parm_ptr = getenv("M90TRACE");
    if (parm_ptr == NULL  || (int) M90_STRLEN(parm_ptr) == 0 ) {
      parm_ptr = M90_TR_FILENAME;
    }
    M90_SPRINTF(mt90tracefile, "%s.%d", parm_ptr, getpid());
    parm_ptr = mt90tracefile;
    level_ptr = getenv("M90LEVEL");
    if (level_ptr != NULL ) {
       m90maxlevel = atoi(level_ptr);
    }	
    file_ptr = fopen(mt90tracefile,"w");
    if (file_ptr == NULL) {
       m90_trace_status = 2;
    }
    else {
       M90_SPRINTF(mt90buffer," TRACE-LEVEL : %d"M90CRLF, m90maxlevel);
       M90_STRCPY(mt90outbuf,M90_TRACE_PREFIX);
       M90_STRCAT(mt90outbuf,mt90buffer);
       M90_TRACE_OUTPUT(mt90outbuf);
       fflush(file_ptr);
    }
  }
#else
  if (m90_trace_status == 88) {
     GetPrivateProfileString((unsigned char *) m90_tr_profentry,
                          (unsigned char *) "trace",
                          (unsigned char *) "N",
                          (unsigned char *) cpos,
                          10,
			  (unsigned char *) M90_TR_INIFILE);
      if (cpos[0] == 'N' || cpos[0] == 'n')
	 m90maxlevel = 0;
      else
	 m90maxlevel=m90ctropt();
      if (m90maxlevel > 0) {
         unsigned char szFileName[512];
         sprintf(szFileName, mt90tracefile, getpid());	
	 parm_ptr = mt90tracefile;
	 file_handle = OpenFile(szFileName, &mt90OfStruct, OF_CREATE);
	 if (file_handle == 0) {
	    M90_EXIT_MSG("trace open failed....");
	    m90_trace_status = 2;
	 }
	 else {
            if (m90_buffered_trace)
               _lclose(file_handle);
	    m90_trace_status = 1;
	    M90_SPRINTF(mt90buffer," TRACE-LEVEL : %d"M90CRLF, m90maxlevel);
	    M90_STRCPY(mt90outbuf,M90_TRACE_PREFIX);
	    M90_STRCAT(mt90outbuf,mt90buffer);
	    M90_TRACE_OUTPUT(mt90outbuf);
	 }
      }
      else {
	 m90_trace_status = 2; /* trace off */
      }
   } /* if 88, first time */
#endif

  if (m90_trace_status == 1) {
  switch (type) {
       case (M90_TR_BUFFER):
       if (ptr != NULL) {
	  M90_SPRINTF(mt90buffer," %s: from %d to %d"M90CRLF, name, pos, len);
	  M90_STRCPY(mt90outbuf,M90_TRACE_PREFIX);
	  M90_STRCAT(mt90outbuf,mt90buffer);
	  M90_TRACE_OUTPUT(mt90outbuf);	
          if (len > m90_tr_buffersize) {
             len = m90_tr_buffersize;
             M90_SPRINTF(mt90buffer," is limited to %d by using %s"M90CRLF, len, M90_TR_BUFFERSIZE_ENTRY);
             M90_STRCPY(mt90outbuf,M90_TRACE_PREFIX);
	     M90_STRCAT(mt90outbuf,mt90buffer);
	     M90_TRACE_OUTPUT(mt90outbuf);
          }
	  p = ((char*)ptr+pos);
	  M90_STRCPY(mt90buffer,"pos:");
	  M90_STRCPY(mt90literal,"chr:");
	  M90_STRCPY(mt90hexlit,"hex:");
          for ( i=1; i <= len; i++) {
	     M90_SPRINTF(cpos, "%3d", i%1000);
	     M90_SPRINTF(hchar, "%3x", (unsigned char) *p);
	     chr = (char) toascii (*p++);
             if (!isprint(chr))
	          chr = '.';
	     M90_SPRINTF(cchar, "%3c", chr);
	     M90_STRCAT(mt90buffer, cpos);
	     M90_STRCAT(mt90hexlit, hchar);
	     M90_STRCAT(mt90literal, cchar);
	     if (! (i % M90_TRACE_MAXCHAR)) {
		M90_STRCAT (mt90buffer, M90CRLF);
                M90_STRCPY(mt90outbuf,M90_TRACE_PREFIX);
                M90_STRCAT(mt90outbuf,mt90buffer);
		M90_TRACE_OUTPUT(mt90outbuf);

		M90_STRCAT (mt90hexlit, M90CRLF);
		M90_STRCPY(mt90outbuf,M90_TRACE_PREFIX);
                M90_STRCAT(mt90outbuf,mt90hexlit);
		M90_TRACE_OUTPUT(mt90outbuf);
		
		M90_STRCAT (mt90literal, M90CRLF);
		M90_STRCPY(mt90outbuf,M90_TRACE_PREFIX);
                M90_STRCAT(mt90outbuf,mt90literal);
		M90_TRACE_OUTPUT(mt90outbuf);
		
		noprint = len - i;
		
		M90_STRCPY(mt90buffer, "pos:");
		if (i >= 1000) 	M90_STRCPY(mt90buffer, "1**:");
		if (i >= 2000) 	M90_STRCPY(mt90buffer, "2**:");
		if (i >= 3000) 	M90_STRCPY(mt90buffer, "3**:");
		if (i >= 4000) 	M90_STRCPY(mt90buffer, "4**:");
		if (i >= 5000) 	M90_STRCPY(mt90buffer, "5**:");
		if (i >= 6000) 	M90_STRCPY(mt90buffer, "6**:");
		if (i >= 7000) 	M90_STRCPY(mt90buffer, "7**:");
		if (i >= 8000) 	M90_STRCPY(mt90buffer, "8**:");
		M90_STRCPY(mt90hexlit, "hex:");
		M90_STRCPY(mt90literal, "chr:");
		
		M90_STRCPY(mt90outbuf,M90_TRACE_PREFIX);
		M90_STRCAT(mt90outbuf,M90CRLF);
		M90_TRACE_OUTPUT(mt90outbuf);
	     }
	  }
	  if (noprint != 0)
	  {
	  M90_STRCAT (mt90buffer, M90CRLF);
	  M90_STRCPY(mt90outbuf,M90_TRACE_PREFIX);
	  M90_STRCAT(mt90outbuf,mt90buffer);
	  M90_TRACE_OUTPUT(mt90outbuf);
	
	  M90_STRCAT (mt90hexlit, M90CRLF);
	  M90_STRCPY(mt90outbuf,M90_TRACE_PREFIX);
          M90_STRCAT(mt90outbuf,mt90hexlit);
	  M90_TRACE_OUTPUT(mt90outbuf);
	
	  M90_STRCAT (mt90literal, M90CRLF);
	  M90_STRCPY(mt90outbuf,M90_TRACE_PREFIX);
          M90_STRCAT(mt90outbuf,mt90literal);
	  }
       }
       else {
	  M90_STRCPY(mt90outbuf,M90_TRACE_PREFIX);
	  M90_SPRINTF(mt90buffer,"buffer from %d to %d is NULL"M90CRLF,
		  pos, len);
       }
       M90_TRACE_OUTPUT(mt90outbuf);
       break;

       case (M90_TR_STRING):
       M90_SPRINTF(mt90buffer," %s:", name);
       M90_STRCPY(mt90outbuf,M90_TRACE_PREFIX);
       M90_STRCAT(mt90outbuf,mt90buffer);
       M90_TRACE_OUTPUT(mt90outbuf);
       if (ptr == NULL)
       {
	        M90_SPRINTF(mt90buffer," is NULL"M90CRLF, name);
       }
       else
       {
         if (len <= 0)
         {
           long int clen = strlen(ptr);
           len = (clen > sizeof(mt90buffer)-1) ? sizeof(mt90buffer)-1 : clen;
         }
         M90_SPRINTF(mt90buffer,"%-0.*s"M90CRLF, (int) len, ptr);
       }
       M90_TRACE_OUTPUT(M90_TRACE_PREFIX);
       M90_TRACE_OUTPUT(mt90buffer);
       break;
     case (M90_TR_UCHAR):
     case (M90_TR_SCHAR): {
       char c;
       uchar = * (char *) ptr;
       if (isprint(uchar))
	       c = uchar;
       else
	       c = '.';
       M90_SPRINTF(mt90buffer," %s: '%c' %#02x "M90CRLF, name, uchar, c);
       M90_STRCPY(mt90outbuf,M90_TRACE_PREFIX);
       M90_STRCAT(mt90outbuf,mt90buffer);
       M90_TRACE_OUTPUT(mt90outbuf);
       break;
	}
     case (M90_TR_WORD):
     case (M90_TR_UWORD):
       uword = * (unsigned short *) ptr;
       M90_SPRINTF(mt90buffer, " %s: %hu"M90CRLF, name, uword);
       M90_STRCPY(mt90outbuf,M90_TRACE_PREFIX);
       M90_STRCAT(mt90outbuf,mt90buffer);
       M90_TRACE_OUTPUT(mt90outbuf);
       break;
     case (M90_TR_INT): {
       int xint = * (int *) ptr;
       M90_SPRINTF(mt90buffer, " %s: %d"M90CRLF, name, xint);
       M90_STRCPY(mt90outbuf,M90_TRACE_PREFIX);
       M90_STRCAT(mt90outbuf,mt90buffer);
       M90_TRACE_OUTPUT(mt90outbuf);
       break;
     }
     case (M90_TR_SWORD):
       sword = * (short *) ptr;
       M90_SPRINTF(mt90buffer," %s: %hd"M90CRLF, name, sword);
       M90_STRCPY(mt90outbuf,M90_TRACE_PREFIX);
       M90_STRCAT(mt90outbuf,mt90buffer);
       M90_TRACE_OUTPUT(mt90outbuf);
       break;
     case (M90_TR_DWORD):
     case (M90_TR_UDWORD):
       dword = * (unsigned long *) ptr;
       M90_SPRINTF(mt90buffer," %s: %lu"M90CRLF, name, dword);
       M90_STRCPY(mt90outbuf,M90_TRACE_PREFIX);
       M90_STRCAT(mt90outbuf,mt90buffer);
       M90_TRACE_OUTPUT(mt90outbuf);
       break;
     case (M90_TR_SDWORD):
       sdword = * (long *) ptr;
       M90_SPRINTF(mt90buffer," %s: %ld"M90CRLF, name, sdword);
       M90_STRCPY(mt90outbuf,M90_TRACE_PREFIX);
       M90_STRCAT(mt90outbuf,mt90buffer);
       M90_TRACE_OUTPUT(mt90outbuf);
       break;
     case (M90_TR_SDOUBLE): /* double */
     case (M90_TR_LDOUBLE): /* long double */
       M90_SPRINTF(mt90buffer," %s: %e"M90CRLF, name, * (double *) ptr);
       M90_STRCPY(mt90outbuf,M90_TRACE_PREFIX);
       M90_STRCAT(mt90outbuf,mt90buffer);
       M90_TRACE_OUTPUT(mt90outbuf);
       break;
     case (M90_TR_SFLOAT):  /* float */
       M90_SPRINTF(mt90buffer," %s: %e"M90CRLF, name, * (float *) ptr);
       M90_STRCPY(mt90outbuf,M90_TRACE_PREFIX);
       M90_STRCAT(mt90outbuf,mt90buffer);
       M90_TRACE_OUTPUT(mt90outbuf);
       break;
     case (M90_TR_HANDLE):
       dword = * (unsigned long *) ptr;
       M90_SPRINTF(mt90buffer," %s: %#08lx"M90CRLF, name, dword);
       M90_STRCPY(mt90outbuf,M90_TRACE_PREFIX);
       M90_STRCAT(mt90outbuf,mt90buffer);
       M90_TRACE_OUTPUT(mt90outbuf);
       break;
     case (M90_TR_STRING_LEN):
       if (ptr == NULL || len == M90_NULL_DATA) {
	 M90_SPRINTF(mt90buffer," %s: is NULL"M90CRLF, name);
       }
       else if (len == M90_NTS) {
	 M90_SPRINTF(mt90buffer," %s: %s"M90CRLF, name, ptr);
       }
       else {
	 M90_SPRINTF(mt90buffer," %s: %-0.*s"M90CRLF, name, (int) len, ptr);
       }
       M90_STRCPY(mt90outbuf,M90_TRACE_PREFIX);
       M90_STRCAT(mt90outbuf,mt90buffer);
       M90_TRACE_OUTPUT(mt90outbuf);
       break;
     case (M90_TR_PTR): {
#if defined (_WIN64)
          M90_SPRINTF(mt90buffer," %s: %#08I64x"M90CRLF, name, * ( char * *)ptr);
#else
          M90_SPRINTF(mt90buffer," %s: %#08lx"M90CRLF, name, * ( char * *)ptr);
#endif
          M90_STRCPY(mt90outbuf,M90_TRACE_PREFIX);
          M90_STRCAT(mt90outbuf,mt90buffer);
          M90_TRACE_OUTPUT(mt90outbuf);
          break;
     }
     case (M90_TR_ENUM): {
          int b;
          memset(&b,0,sizeof(b));
          if (ptr) {
             memcpy(&b, ptr, sizeof(b));
          }
          M90_SPRINTF(mt90buffer," %s: %#08lx"M90CRLF, name, b);
          M90_STRCPY(mt90outbuf,M90_TRACE_PREFIX);
          M90_STRCAT(mt90outbuf,mt90buffer);
          M90_TRACE_OUTPUT(mt90outbuf);
          break;
     }
     case (M90_TR_ENTRY): {
	if (lazy_exit == 1) {
	   lazy_exit = 0;
	   mt90level--;
	}
	mt90level++;
	M90_SPRINTF(mt90buffer," %03ld>> ENTER: %s"M90CRLF, mt90level, name);
	M90_TRACE_OUTPUT(mt90buffer);
	break;
     }
     case (M90_TR_EXIT): {
	if (lazy_exit == 1) {
	   lazy_exit = 0;
	   mt90level--;
	}
	M90_SPRINTF(mt90buffer," %03ld<< EXIT : %s"M90CRLF, mt90level, name);
	M90_TRACE_OUTPUT(mt90buffer);
	lazy_exit = 1;
	break;
     }
     case (M90_TR_MSG):
       M90_SPRINTF(mt90buffer," %s"M90CRLF, name);
       M90_TRACE_OUTPUT(mt90buffer);
       break;
    }
  }

  return;
}

void m90centry( char * name )
{
  M90TRACE (M90_TR_ENTRY, name, 0);
}

void m90cexit( char * name )
{
  M90TRACE(M90_TR_EXIT, name, 0);
}

void m90cint2( char * name, signed short i)
{
  M90TRACE(M90_TR_SWORD, name, &i);
}

void m90cint4( char * name, signed long i)
{
  M90TRACE(M90_TR_SDWORD, name, &i);
}

void m90cuint2( char * name, unsigned short i)
{
  M90TRACE(M90_TR_UWORD, name, &i);
}

void m90cuint4( char * name, unsigned long i)
{
  M90TRACE(M90_TR_UDWORD, name, &i);
}

#ifdef WIN32
unsigned int  m90ctropt()
{

  short int iRet;
  HWND hwnd = 0;
  DLGPROC dlgprc;
  iRet = TRUE;
  if (FindWindow("#32770", m90_tr_appname) != NULL) {
     mt90ProcDebug(NULL, WM_INITDIALOG, 0, 0);
     iRet = TRUE;
  }
  else {
    hwnd = GetDesktopWindow();
    dlgprc = (DLGPROC) MakeProcInstance(mt90ProcDebug, m90s_hModule);
    iRet = DialogBox(m90s_hModule, MAKEINTRESOURCE(DEBUGBOX), hwnd, dlgprc);
    FreeProcInstance((FARPROC) dlgprc);
  }
  if (iRet == TRUE) {
     if (mt90tracefile != NULL) {
	iRet = atoi(mt90tracelevel);
	if (iRet == 0) {
	   iRet=1;
	}
     }
  }
  else {
     if (iRet == FALSE) {
	iRet = 0;
     }
     else {
	if (iRet == -1) {
	   M90_EXIT_MSG(" Trace Dialog Box Failed!");
	   iRet = 0;
	}
     }
  }
  return(iRet);
}

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

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

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

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


BOOL PASCAL mt90ProcDebug(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
  int count;
  int level;
  unsigned char szModuleName[260];

    switch (message) {
	case WM_INITDIALOG:
	   mt90CenterDialog(hDlg);
	   szModuleName[0] = '\0';
	   GetPrivateProfileString((unsigned char *) m90_tr_profentry,
                          (unsigned char *) M90_TR_FILENAME_ENTRY,
                          (unsigned char *) M90_TR_FILENAME,
                          (unsigned char *) mt90tracefile,
                          sizeof(mt90tracefile),
			  (unsigned char *) M90_TR_INIFILE);
	   GetPrivateProfileString((unsigned char *) m90_tr_profentry,
                          (unsigned char *) M90_TR_LEVEL_ENTRY,
                          (unsigned char *) "1",
                          (unsigned char *) mt90tracelevel,
                          sizeof(mt90tracelevel),
			  (unsigned char *) M90_TR_INIFILE);
	   m90_tr_buffersize = GetPrivateProfileInt((unsigned char *) m90_tr_profentry,
                          (unsigned char *) M90_TR_BUFFERSIZE_ENTRY,
                          m90_tr_buffersize,
			  (unsigned char *) M90_TR_INIFILE);

           if (mt90tracefile[1] != ':') {
	      if (!M90_STRCHR(mt90tracefile, '\\')) {
		 WORD wReturn;
		 wReturn = _getdrive();
		 _getdcwd(wReturn, szModuleName, sizeof(szModuleName));
	      }
	   }	
	   if (szModuleName[0] != '\0')
	      if (szModuleName[M90_STRLEN(szModuleName)-1] != '\\')
		 M90_STRCAT(szModuleName, "\\");
	   M90_STRCAT(szModuleName, mt90tracefile);
	   {
	     char szPid[11];
	     GetPrivateProfileString((unsigned char *) m90_tr_profentry,
				     (unsigned char *) "AppendProcessID",
				     (unsigned char *) "n",
				     (unsigned char *) szPid, sizeof(szPid),
				     (unsigned char *) M90_TR_INIFILE);
	     if (szPid[0] == 'Y' || szPid[0] == 'y') {
	       M90_SPRINTF(szPid, ".%d", getpid());
	       M90_STRCAT(szModuleName, szPid);
	     }
	   }
	   M90_STRCPY(mt90tracefile, szModuleName);
           SetDlgItemText(hDlg,M90_TRACELEVEL, mt90tracelevel);
           SetDlgItemText(hDlg,M90_TRACEFILE, mt90tracefile);
	   GetModuleFileName(NULL, szModuleName, sizeof(szModuleName));
	   SetDlgItemText(hDlg,M90_APPLICATION, szModuleName);
	   return (TRUE);
	   break;
	case WM_COMMAND:
	   switch (wParam) {
	      case IDOK: {
		 count = GetDlgItemText(hDlg,M90_TRACELEVEL, mt90tracelevel, sizeof(mt90tracelevel));
		 mt90tracelevel[count] = '\0';
		 level = atoi(mt90tracelevel);
		 count = GetDlgItemText(hDlg,M90_TRACEFILE, mt90tracefile, sizeof(mt90tracefile));
		 mt90tracefile[count] = '\0';
		 EndDialog(hDlg, TRUE);
		 return (TRUE);
	      }
	      break;
	      case IDCANCEL: {
		 EndDialog(hDlg, FALSE);
		 return (TRUE);
	      }
	      break;
	   }
    }
    return (FALSE);
}

void mt90TraceSwitch(int Level)
{
   if (Level > 0) {
      m90maxlevel = Level;
      if (m90_trace_status == M90_TRACEINIT)
	 M90TRACEINIT(M90_TRACEINIT);
      m90_trace_status = M90_TRACEON;
   }
   else
      if (m90_trace_status == M90_TRACEON)
	 m90_trace_status = M90_TRACEOFF;
}

void mt90SetTraceFileName(UCHAR *ptr)
{
   UCHAR *deftracefile="trace.log";
   if (!ptr)
      ptr = deftracefile;
   if(M90_STRCMP(mt90tracefile, ptr))
      m90_trace_status=M90_TRACEINIT;
   M90_STRNCPY(mt90tracefile, ptr, sizeof(mt90tracefile)-1);
   if (m90_trace_status==M90_TRACEINIT)
      M90TRACEINIT(M90_TRACEINIT);
}

void mt90TraceOutPut(int *file_handle, char *szBuffer)
{
    if (mt90level <= m90maxlevel)
    {
        if (m90_buffered_trace)
        {
	    unsigned char szFileName[512];
	    sprintf(szFileName, mt90tracefile, getpid());	
            *file_handle = (OpenFile((unsigned char *) szFileName, &mt90OfStruct, OF_REOPEN | OF_WRITE));
            if (*file_handle == 0)
	            FatalAppExit(0,"trace file won't open!!!!!");
            _llseek(*file_handle, 0L, 2);
            _lwrite(*file_handle,szBuffer,M90_STRLEN(szBuffer));
            _lclose(*file_handle);
        }
        else
            _lwrite(*file_handle,szBuffer,M90_STRLEN(szBuffer));
        m90_line_count++;
        if (m90_line_count >= m90_flush_after)
        {
            _lclose(*file_handle);
            *file_handle = (OpenFile((unsigned char *) mt90tracefile, &mt90OfStruct, OF_REOPEN | OF_WRITE));
            if (*file_handle == 0)
	            FatalAppExit(0,"trace file won't open!!!!!");
            _llseek(*file_handle, 0L, 2);
            m90_line_count = 0;
        }
    }
}
#endif
.CM *-END-* code ----------------------------------------
.SP 2
***********************************************************
