/*@P************************************************************************
 * File           : TSTMOV.C
 * Project        : EVERLOCK EVMOV3.DLL Test Application
 * Author         : M. Brendan Van Horn
 * Compiler       : Borland C++ v4.02
 * Description    :
 *
 * Copyright (c) 1994-95 Az-Tech Software, Inc.
 * ALL RIGHTS RESERVED
 ************************************************************************P@*/

#define STRICT
#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include "sb.h"
#include "tstmov.h"

// disable Microsoft warning for unknown pragmas
#pragma warning (disable: 4068)

/***************************************************************************
 * Function Prototypes.
 ***************************************************************************/
void CenterDialog( HWND hDlg );
void ParseCommand( SB *pSB, LPSTR lpCmdLine );
int NormalizeStatus( int status );
void GlobalDialogBox( HINSTANCE hInstance, FARPROC dlgProc, UINT resId );
LRESULT CALLBACK RegInfoDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam );
void RegInfoOnCommand( HWND, int, HWND, UINT );
BOOL RegInfoOnInitDialog( HWND, HWND, LPARAM );

// if you are using this code in a C++ program you must define the 
// evmov3 function as an 'extern "C"' function to avoid link errors
// caused by name mangling.

#ifdef __cplusplus
extern "C" int __far __pascal evmov3( SB __far *lpUserSB );
#else
int __far __pascal evmov3( SB __far *lpUserSB );
#endif

/***************************************************************************
 * Global Variables.
 ***************************************************************************/
char szAppName[] = "EVERLOCK EVMOV3.DLL Test Application";
UINT errFlags = MB_ICONSTOP | MB_OK;
UINT okFlags = MB_ICONINFORMATION | MB_OK;
UINT confFlags = MB_ICONQUESTION | MB_OKCANCEL;
SB sb;
char szText[255];

char szInstall[] = "Installing Authorization from %s to %s.\n"
                   "Select Ok to continue, or Cancel to abort.";

char szUninstall[] = "Uninstalling Authorization from %s to %s.\n"
                     "Select Ok to continue, or Cancel to abort.";

#pragma argsused
int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpCmdLine,
                    int nCmdShow )
{
   int comp_status;
   HCURSOR hSaveCursor, hWaitCursor;

   // if we are a second instance, just quit
   if ( hPrevInst )
      return 0;

   // get the handle of the hourglass (waiting) cursor
   hWaitCursor = LoadCursor( NULL, IDC_WAIT );

   // turn on the waiting cursor
   hSaveCursor = SetCursor( hWaitCursor );

   // zero out the contents of the SB structure
   memset( &sb, 0, sizeof( SB ) );

   // initialize the contents of the SB buffer
   strncpy( sb.id, "AZSB", 4 );

   // parse out the command line parameters
   ParseCommand( &sb, lpCmdLine );

   // get the initial information about the move operation
   sb.func = 0;
   comp_status = evmov3( &sb );

   // restore the original cursor
   SetCursor( hSaveCursor );

   // display the results of the check
   if ( comp_status )
   {
      // format the error message
      sprintf( szText, "EVMOV3.DLL Error %04X!", comp_status );

      // display the error message
      MessageBox( NULL, szText, szAppName, errFlags );

      // return to the OS
      return NormalizeStatus( comp_status );

   } else if ( sb.stat1 ) {

      // format the error message
      sprintf( szText, "Security Error %04X-%04X-%04X!", sb.stat1,
               sb.stat2, sb.stat3 );

      // display the error message
      MessageBox( NULL, szText, szAppName, errFlags );

      // return to the OS
      return NormalizeStatus( sb.stat1 );
   }

   // format the confirmation message
   if ( !sb.uninst )
      sprintf( szText, szInstall, sb.source, sb.target );
   else
      sprintf( szText, szUninstall, sb.source, sb.target );

   // ask the user if they would like to move
   comp_status = MessageBox( NULL, szText, szAppName, confFlags );

   // check the user's response
   if ( IDCANCEL == comp_status )
   {
      // let the user know that they cancelled
      MessageBox( NULL, "Ending EVMOV3 at user's request.", szAppName, okFlags );

      // return to the operating system
      return 1;
   }

   // do we need to get the non-verified registration info?
   if ( sb.reg && !sb.uninst )
   {
      // yep, so get the reginfo
      GlobalDialogBox( hInstance, (FARPROC) RegInfoDlgProc, IDD_REGINFO );

      // if the user aborted, return to our caller to handle error
      if ( sb.stat1 )
      {
         // inform the user why we are ending
         MessageBox( NULL, "EVMOVE ending at user's request.", szAppName,
                     errFlags );

         // return to the operating system
         return NormalizeStatus( sb.stat1 );
      }
   }

   // turn on the waiting cursor
   hSaveCursor = SetCursor( hWaitCursor );

   // perform the actual move operation
   sb.func = 1;
   comp_status = evmov3( &sb );

   // restore the original cursor
   SetCursor( hSaveCursor );

   // display the results of the check
   if ( comp_status )
   {
      // format the error message
      sprintf( szText, "EVMOV3.DLL Error %04X!", comp_status );

      // display the error message
      MessageBox( NULL, szText, szAppName, errFlags );

      // return to the OS
      return NormalizeStatus( comp_status );

   } else if ( sb.stat1 ) {

      // format the error message
      sprintf( szText, "Security Error %04X-%04X-%04X!", sb.stat1,
               sb.stat2, sb.stat3 );

      // display the error message
      MessageBox( NULL, szText, szAppName, errFlags );

      // return to the OS
      return NormalizeStatus( sb.stat1 );
   }

   // let the user know we were successfull
   MessageBox( NULL, "Authorization Move Successfull!", szAppName, okFlags );

   // return to the OS
   return 0;
}

//@PB
void GlobalDialogBox( HINSTANCE hInstance, FARPROC dlgProc, UINT resId )
{
   DLGPROC lpProc;

   // create, display and release the dialog box
   lpProc = (DLGPROC) MakeProcInstance( dlgProc, hInstance );
   DialogBox( hInstance, MAKEINTRESOURCE( resId ), NULL, lpProc );
   FreeProcInstance( (FARPROC) lpProc );
}

//@PB
void CenterDialog( HWND hDlg )
{
   RECT rc, rcParent;
   int newX, newY, centerX, centerY;

   // get screen rectangle size and dialog box rectangle size
   GetWindowRect( GetDesktopWindow(), &rcParent );
   GetWindowRect( hDlg, &rc );

   // calculate center of screen
   centerX = ( rcParent.left + rcParent.right  ) / 2;
   centerY = ( rcParent.top  + rcParent.bottom ) / 2;

   // calculate new origin of dialog box
   newX = centerX - ( ( rc.right  - rc.left ) / 2 );
   newY = centerY - ( ( rc.bottom - rc.top  ) / 2 );

   // set the dialog box's new location
   SetWindowPos( hDlg, NULL, newX, newY, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE );
}

//@PB
int NormalizeStatus( int status )
{
   int temp;

   // get the hundreds digit from the error code
   temp = ( ( status & 0x0F00 ) >> 8 ) * 100;

   // add in the tens digit from the error code
   temp += ( ( status & 0x00F0 ) >> 4 ) * 10;

   // finally, add in the ones digit
   temp += status & 0x000F;

   // return the normalized status value to our caller
   return temp;
}

//@PB
void ParseCommand( SB *pSB, LPSTR lpCmdLine )
{
   int pos;
   int state;
   int i;
   int len;
   BOOL fLoop;

   // get the length of the command line
   len = lstrlen( lpCmdLine );

   // setup variables
   pos = state = 0;
   fLoop = TRUE;

   // loop to scan for cmd line arguments
   while ( fLoop && pos <= len )
   {
      // handle the different things we can find on the cmdline
      switch ( lpCmdLine[pos] )
      {
         case '\0':

            // we're at the end, stop searching
            fLoop = FALSE;
            break;

         case ' ':

            // skip the space character
            break;

         default:

            // copy the arguments to the from and to path buffers
            switch ( state )
            {
               case 0:     // from path

                  // setup the starting position of the copy destination
                  i = 0;

                  // save the source media
                  while ( ' ' != lpCmdLine[pos] && '\0' != lpCmdLine[pos] )
                     pSB->source[i++] = lpCmdLine[pos++];

                  // set the state to get the dest media next
                  state++;

                  break;

               case 1:     // to path

                  // setup the starting position of the copy destination
                  i = 0;

                  // save the destination media
                  while ( ' ' != lpCmdLine[pos] && '\0' != lpCmdLine[pos] )
                     pSB->target[i++] = lpCmdLine[pos++];

                  // set the state to get nothing next
                  state++;

                  break;
            }
      }

      // move to the next character
      pos++;
   }
}

//@PB
LRESULT CALLBACK RegInfoDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch ( msg )
    {
        HANDLE_MSG( hDlg, WM_COMMAND,        RegInfoOnCommand       );
        HANDLE_MSG( hDlg, WM_INITDIALOG,     RegInfoOnInitDialog    );
    }

    return FALSE;
}

#pragma argsused
void RegInfoOnCommand( HWND hDlg, int id, HWND hCtl, UINT codeNotify )
{
   int ctlId;

   switch ( id )
   {
      case IDOK:

         // get the parameters entered into the edit controls
         GetDlgItemText( hDlg, IDC_NAME,     sb.rname, 51 );
         GetDlgItemText( hDlg, IDC_COMPANY,  sb.rcomp, 51 );
         GetDlgItemText( hDlg, IDC_LOCATION, sb.rloc,  51 );

         // show that there was no error
         sb.stat1 = 0x0000;

         break;

      case IDCANCEL:

         // flag that the user hit abort
         sb.stat1 = 0x7001;

         break;

      default:

         // we can't handle it so let someone else do the dirty work
         return;
   }

   // finish the dialog and clear it out
   EndDialog( hDlg, 0 );
}

#pragma argsused
BOOL RegInfoOnInitDialog( HWND hWnd, HWND hWndFocus, LPARAM lParam )
{
   HWND hDlgItem = NULL;
   char szTemp[1] = "\0";

   // blank out the initial edit field contents
   SetDlgItemText( hWnd, IDC_NAME,     szTemp );
   SetDlgItemText( hWnd, IDC_COMPANY,  szTemp );
   SetDlgItemText( hWnd, IDC_LOCATION, szTemp );

   // get the window handle of our default control
   hDlgItem = GetDlgItem( hWnd, IDC_NAME );

   // set the focus to this control
   SetFocus( hDlgItem );

   // center the dialog box in the display screen
   CenterDialog( hWnd );

   // return success to our caller
   return FALSE;
}
