#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <phapi.h>
#include "sb.h"
#include "evchkp.h"

SB sb;
short do_check( char *pPath );
void  do_output( void );
short EVCHKP(SB far *lpSB);
short init_real_buf(void);
void  free_real_buf(void);

static BYTE far *real_buf = 0;
static BYTE far *ptr_real_buf;

#pragma argsused
int main( int argc, char **argv )
{
   short i, comp_status;

   printf( "\nThe size of the SB is %d\n\n", sizeof( SB ) );

   if(!init_real_buf())
      return -1;

   comp_status = do_check( argv[0] );

   if( comp_status == 0 )        /* If EVCHKP operated, check return code */
   {
      if( sb.stat1 == 0 )        /* If authorization check passed */
        do_output();             /* print information */
     else
        printf( "EVCHKP Authorization Error = %04X-%04X-%04X\n",
                sb.stat1, sb.stat2, sb.stat3 );
   } else
      printf( "EVCHKP Execution Error = %04X\n", comp_status );

   free_real_buf();

   return comp_status;
}

/* Initialize fields for EVCHKP call */

short do_check( char *pPath )
{
   strncpy(sb.id, "AZSB", 4);
   sb.stat1 = 0x7240;            /*  Initialize to invalid return code.  */
   sb.func = 1;                  /*  Code 0, 1, or 2.  */
   sb.snp = 0;                   /* Verify product serial number, should be 0 if not to be checked.*/
   sb.pin = 1804054920;

   strcpy( sb.source, pPath ); /* Pointer File Subdirectory */
   strcpy( strrchr( sb.source, '\\' ) + 1, "PCHECK.EXE" );

   return EVCHKP(&sb);
}

short EVCHKP(SB far *lpSB)
{
   REGS16 r;
   int i;
   char *p;


   memset(&r, 0, sizeof(r));

   p = (char far *)lpSB;

   for(i=0; i<sizeof(SB); i++)
   {
      real_buf[i] = p[i];
   }

   if(DosRealFarCall(DosProtToReal((PVOID) evchkp), &r, 0, 
                        -2, ptr_real_buf) != 0)
   {
      printf("DosRealFarCall - Failed");
      return -2;
   }

   for(i=0; i<sizeof(SB); i++)
   {
      p[i] = real_buf[i];
   }

   return r.ax;
}

short init_real_buf(void)
{
   unsigned short sel, para;

   if(DosAllocRealSeg(sizeof(SB), &para, &sel) != 0)
   {
      printf("Insufficient conventional memory");
      return 0;
   }

   real_buf = MAKEP(sel, 0);
   ptr_real_buf = MAKEP(para, 0);
   return 1;
}

void free_real_buf(void)
{
   DosFreeSeg(SELECTOROF(real_buf));
}

void do_output( void )
{
   printf( "          Return Code: %04X-%04X-%04X\n",
      sb.stat1, sb.stat2, sb.stat3 );

   printf( "         Drive Loaded: %c\n", sb.drv );
   printf( " Authorization Device: %c\n", sb.auth );
   printf( "         Product Type: %c ", sb.ptype );

   switch ( sb.ptype )
   {
      case 'P':   printf( "Original Product\n" );  break;
      case 'I':   printf( "Installed Copy\n"   );  break;
      case 'E':   printf( "Encrypt Only\n" );      break;
      case 'C':   printf( "CPU-Lock Install\n" );  break;
      default:    printf( "Unknown Type\n"     );  break;
   }

   printf( "        Function Code: %d\n", sb.func );
   printf( "         Product Name: %s\n", sb.prod );
   printf( "   Product Serial Num: %lu\n", sb.snp );
   printf( "           NUC Handle: %u\n", sb.hnuc );
   printf( "Authorization Version: %u\n", sb.avers );
   printf( "Execution Count Limit: " );

   if ( 0xffff == sb.ecl )
      printf( "Unlimited\n" );
   else
      printf( "%u\n", sb.ecl );

   printf( "          Date Format: %u ", sb.dft );

   switch ( sb.dft )
   {
      case 0:  printf( "MM/DD/YY\n" );    break;
      case 1:  printf( "DD/MM/YY\n" );    break;
      case 2:  printf( "YY/MM/DD\n" );    break;
      default: printf( "Unknown\n" );     break;
   }

   printf( "    Expire Date Limit: " );

   if ( 0xffff == sb.edl )
      printf( "Unlimited\n" );
   else
      printf( "%u\n", sb.edl );

   printf( "          Expire Date: %s\n", sb.ed );
   printf( "             Checksum: %u\n", sb.chksum );
   printf( "   Network User Count: %u\n", sb.nuc );
   printf( "   Network User Limit: " );

   if ( 0xffff == sb.nul )
      printf( "Unlimited\n" );
   else
      printf( "%u\n", sb.nul );

   printf( "  Install Counts Left: %u\n", sb.icr );
   printf( "    Registration Type: " );

   switch ( sb.rtype )
   {
      case 'U':   printf( "None\n" );           break;
      case 'V':   printf( "Verified\n" );       break;
      case 'N':   printf( "Non-verified\n" );   break;
      default:    printf( "Unknown\n" );        break;
   }

   printf( "      Registered Name: %s\n", sb.rname );
   printf( "   Registered Company: %s\n", sb.rcomp );
   printf( "  Registered Location: %s\n", sb.rloc );
   printf( "      Registered Date: %s\n", sb.rdate );
   printf( "         Current Date: %s\n", sb.cdate );
   printf( "        Secure String: %s\n", sb.secstr );
}
