/***************************************************************************
 *                                                                         *
 *   GALDBGD.C                                                             *
 *                                                                         *
 *   Copyright (c) 1998 Galacticomm, Inc.         All Rights Reserved.     *
 *                                                                         *
 *   Debug phase display process (see DBGXPHP option in GALDEBUG.MSG).     *
 *                                                                         *
 *                                           - J. Alvrus    02/06/1998     *
 *                                                                         *
 ***************************************************************************/

#include <windows.h>
#include <windowsx.h>
#include <mem.h>
#include <stdio.h>

/* define boolean type stuff if not already */
#if !defined(BOOL)
#define BOOL int
#endif
#if !defined(FALSE)
#define FALSE 0
#endif
#if !defined(TRUE)
#define TRUE 1
#endif

#define INIFILE ".\\galdbgd.ini"   /* .INI file for configurable params    */
#define NUMPHS 16                  /* # phases in buffer (from PHASEDBG.H) */
#define LOGWAIT 10                 /* default seconds to wait for update   */
                                   /* before saving phase info             */
#define REBOOTWAIT 300             /* default seconds to wait before       */
                                   /* rebooting the server                 */
#define DM_REBOOT   (WM_USER+1)    /* debug msg: enable/disable reboot     */

unsigned int LogWait;              /* default update seconds               */
unsigned int RebootWait;           /* maximum reboot wait time             */
BOOL RebootFlag=FALSE;             /* should we reboot after RebootWait?   */
BOOL NeedUpdate=FALSE;             /* have we received new phase info?     */
BOOL GotFirstUpdate=FALSE;         /* have we received first update?       */
int MissedUpdateCounter=0;         /* watchdog counter for lockup/abort    */
char PhaseInfoString[NUMPHS*100];  /* phase desc shouldn't exceed 80 cols  */

void
ReadDefault(                       /* Read the default value from .ini     */
unsigned int* pValue,              /*  Pointer to the variable to be set   */
unsigned int DefaultValue,         /*  Default value if not found          */
char const* iniString)             /*  ini variable to search for          */
{
     char DefaultStg[100];
     char ReturnStg[100];
     DWORD dwDuh;

     memset(ReturnStg,0,100);
     sprintf(DefaultStg,"%u",DefaultValue);
     dwDuh=GetPrivateProfileString("Settings",iniString,DefaultStg,ReturnStg,100,INIFILE);
     if (dwDuh) {
     }
     *pValue=atoi(ReturnStg);
}

BOOL                              /*   return TRUE if it is WinNT         */
isWinNT(VOID)                      /* checks for Windows NT                */
{
     OSVERSIONINFO versionInfo;

     versionInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
     GetVersionEx(&versionInfo);
     if (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
          return(TRUE);
     }
     else {
          return(FALSE);
     }
}

void
hdlPaint(                          /* handle WM_PAINT for main window      */
HWND hwnd)                         /*   handle to window to paint          */
{
     HDC hdc;                      /* device context for output            */
     PAINTSTRUCT ps;               /* paint info (for BeginPaint/EndPaint) */
     RECT r;                       /* window client rectangle              */

     /*  get display area */
     GetClientRect(hwnd,&r);

     /* set up output context */
     hdc=BeginPaint(hwnd,&ps);
     SetBkMode(hdc,TRANSPARENT);
     SetTextColor(hdc,GetSysColor(COLOR_WINDOWTEXT));
     SelectFont(hdc,GetStockFont(OEM_FIXED_FONT));

     /* show phase info */
     DrawText(hdc,PhaseInfoString,-1,&r,DT_LEFT|DT_NOCLIP);

     EndPaint(hwnd,&ps);
}

void
RebootServer(void)
{

     HANDLE hFile;

     hFile=CreateFile("galdbgd.txt",GENERIC_WRITE,0,NULL,OPEN_ALWAYS
                          ,FILE_ATTRIBUTE_NORMAL,0);
     if (hFile != 0) {
          DWORD nBytes;

          SetFilePointer(hFile,0L,NULL,FILE_END);
          WriteFile(hFile,"\n\nServer Rebooted\n",
           (DWORD)lstrlen("\n\nServer Rebooted\n"),
           &nBytes,NULL);
          CloseHandle(hFile);
     }
     system("type wgserver.out >> galdbgd.txt");

     if (isWinNT()) {
          HANDLE hToken;
          TOKEN_PRIVILEGES tkp;

          if (OpenProcessToken(GetCurrentProcess(),
           TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken)) {
               LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);
               tkp.PrivilegeCount=1;
               tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
               AdjustTokenPrivileges(hToken,FALSE,&tkp,0,NULL,0);
               if (GetLastError() == ERROR_SUCCESS) {
                    ExitWindowsEx(EWX_REBOOT|EWX_FORCE,0);
               }
          }
     }
     else {
          ExitWindowsEx(EWX_REBOOT|EWX_FORCE,0);
     }
}

long FAR PASCAL
WndProc(                           /* main window Window Procedure         */
HWND hwnd,
WORD msg,
WORD wparm,
LONG lparm)
{
     switch (msg) {
     case WM_PAINT:
          hdlPaint(hwnd);
          return(0);
     case WM_COPYDATA:
          /* This is where we get the data from Worldgroup.  Just put it   */
          /* in our global buffer and set the "need update" flag.          */
          lstrcpy(PhaseInfoString,((COPYDATASTRUCT *)lparm)->lpData);
          NeedUpdate=GotFirstUpdate=TRUE;
          return(1);
     case WM_DESTROY:
          PostQuitMessage(0);
          return(0);
     case DM_REBOOT:
          RebootFlag=(wparm != 0);
          return(0);
     }
     return(DefWindowProc(hwnd,msg,wparm,lparm));
}

VOID CALLBACK
TimerProc(                         /* 1 Hz timer handler                   */
HWND hwnd,
UINT uMsg,
UINT idEvent,
DWORD dwTime)
{
     HANDLE hFile;                 /* output file handle                   */
     DWORD nBytes;                 /* number of bytes written by WriteFile */
     SYSTEMTIME st;                /* buffer for current system time       */
     char TimeStamp[sizeof("\r\n1998-02-06 17:28:39\r\n")];
                                   /* buffer for time stamp                */

     /* take care of unused params */
     (void)uMsg;
     (void)idEvent;
     (void)dwTime;

     /* update display if needed */
     if (NeedUpdate) {
          NeedUpdate=FALSE;
          InvalidateRect(hwnd,NULL,TRUE);
          MissedUpdateCounter=0;
          return;
     }
     if (!GotFirstUpdate) {
          return;
     }
     /* else, check for lockup/abort */
     MissedUpdateCounter++;
     if (MissedUpdateCounter == LogWait) {
          /* form time-stamp string */
          GetLocalTime(&st);
          wsprintf(TimeStamp,"\r\n%04d-%02d-%02d %02d:%02d:%02d\r\n"
                  ,st.wYear,st.wMonth,st.wDay
                  ,st.wHour,st.wMinute,st.wSecond);


          /* save last phase info received from Worldgroup */
          hFile=CreateFile("galdbgd.txt",GENERIC_WRITE,0,NULL,OPEN_ALWAYS
                          ,FILE_ATTRIBUTE_NORMAL,0);
          if (hFile != 0) {
               SetFilePointer(hFile,0L,NULL,FILE_END);
               WriteFile(hFile,TimeStamp,(DWORD)lstrlen(TimeStamp),&nBytes,NULL);
               WriteFile(hFile,PhaseInfoString,(DWORD)lstrlen(PhaseInfoString)
                        ,&nBytes,NULL);
               CloseHandle(hFile);
          }
     }
     else if (RebootFlag && MissedUpdateCounter == RebootWait) {
          RebootServer();
     }
}


int PASCAL
WinMain(                           /* main program entry point             */
HANDLE hInst,
HANDLE hPrevInst,
LPSTR cmdlin,
int ShowCmd)
{
     HWND hwnd;                    /* main window handle                   */
     MSG wm;                       /* message structure for message loop   */
     WNDCLASS wc;                  /* buffer for creating main window class*/
     static char WinClassName[]="GALDBGD"; /* main window class name       */

     /* take care of unused params */
     (void)hPrevInst;
     (void)cmdlin;
     (void)ShowCmd;

     ReadDefault(&LogWait,LOGWAIT,"LogWait");
     ReadDefault(&RebootWait,REBOOTWAIT,"RebootWait");
     if (RebootWait <= LogWait) {
          RebootWait=LogWait+1;
     }
     /* set up window class */
     memset(&wc,0,sizeof(WNDCLASS));
     wc.style=0;
     wc.lpfnWndProc=(WNDPROC)WndProc;
     wc.hInstance=hInst;
     wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);
     wc.hCursor=LoadCursor(NULL,IDC_ARROW);
     wc.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
     wc.lpszClassName=WinClassName;
     RegisterClass(&wc);

     /* start up this instance */
     hwnd=CreateWindow(WinClassName,"Phase Transitions"
                      ,WS_OVERLAPPEDWINDOW
                      ,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT
                      ,NULL,NULL,hInst,NULL);
     ShowWindow(hwnd,SW_SHOWDEFAULT);
     UpdateWindow(hwnd);

     /* start 1 Hz update timer */
     SetTimer(hwnd,0,1000,(TIMERPROC)TimerProc);

     /* process messages */
     while (GetMessage(&wm,NULL,0,0)) {
          TranslateMessage(&wm);
          DispatchMessage(&wm);
     }
     return(wm.wParam);
}


