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

#define STRICT
#include <windows.h>
#include <windowsx.h>
#include <toolhelp.h>
#include <stdio.h>
#include <string.h>
#include <memory.h>

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

/***************************************************************************
 * Secure Information Block created by the Safe-D front end.
 ***************************************************************************/
typedef struct tagSIB               // 512 bytes total
{
   char  id[4];                  // 000 ID literal to scan for 'AZSB'
   char  drv;                    // 004 Drive Pgm was loaded from (ASCII)
   char  auth;                   // 005 Auth Device (A,B,C=disk, 1,2,3=LPT#)
   char  ptype;                  // 006 product type
   char  prod[9];                // 007 Product Name (ASCIIZ)
   unsigned long snp;            // 016 product serial number
   unsigned short hnuc;          // 020 NUC file handle
   unsigned short avers;         // 022 Authorization Version
   unsigned short ecl;           // 024 Exec-Count Limit
   short dft;                    // 026 0 = m/d/y, 1 = d/m/y, 2 = y/m/d
   unsigned short edl;           // 028 Expire-Days Limit
   unsigned short etl;           // 030 Elapsed time on last day (etl * 2)secs
   char  ed[9];                  // 032 Expire-Date (ASCIIZ)
   char  checksum;               // 041 checksum
   unsigned short nuc;           // 042 Network Concurrent-Users current count
   unsigned short nul;           // 044 Network Concurrent-Users Limit
   short icr;                    // 046 install counts remaining
   char  accflg[8];              // 048 Access Flags 1-64
   char  usrdat[8];              // 048 User-Data
   char  rtype;                  // 064 Register Type (V,N,U=Ver,Non-Ver, None)
   char  rname[51];              // 065 register to name (ASCIIZ)
   char  rcomp[51];              // 116 register to company (ASCIIZ)
   char  rloc[51];               // 167 register to location (ASCIIZ)
   char  rdate[9];               // 218 Register Date (ASCIIZ)
   char  cdate[9];               // 227 Current System Date (ASCIIZ)
   char  rsrvd2[20];             // 236 Reserved
   char  secstr[256];            // 256 Secure-String (ASCIIZ)
} SIB;

/***************************************************************************
 * SIB created on the global heap for finding by a user application.
 ***************************************************************************/
typedef struct tagWINSIB
{
   HINSTANCE hi;
   SIB sib;
} WINSIB;

typedef WINSIB *PWINSIB;
typedef WINSIB __far *LPWINSIB;
typedef WINSIB __near *NPWINSIB;

/***************************************************************************
 * Function Prototypes.
 ***************************************************************************/
LPWINSIB FindSIB( HINSTANCE hInst );

/***************************************************************************
 * Global Variables.
 ***************************************************************************/
char szAppName[] = "EVERLOCK SIB Test Application";
UINT errFlags = MB_ICONSTOP | MB_OK;
UINT okFlags = MB_ICONINFORMATION | MB_OK;
LPWINSIB lpWS;
char szText[255];

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

   /* turn on the waiting cursor */
   hSaveCursor = SetCursor( LoadCursor( NULL, IDC_WAIT ) );

   /* hunt for the SIB */
   lpWS = FindSIB( hInstance );

   /* restore the original cursor */
   SetCursor( hSaveCursor );

   /* display the results of the check */
   if ( NULL == lpWS )
   {
      /* display the error message */
      MessageBox( NULL, "Can't locate the SIB!", szAppName, errFlags );

      /* return control to the OS */
      return 0;
   }

   /* display the success message */
   MessageBox( NULL, (LPCSTR) lpWS->sib.secstr, szAppName, okFlags );

   /* unlock the SIB since we are done with it */
   GlobalUnlockPtr( lpWS );

   /* return to the OS */
   return 0;
}

LPWINSIB FindSIB( HINSTANCE hInst )
{
   LPWINSIB lpSIB;
   GLOBALENTRY ge;

   /* initialize the global entry structure with the proper values */
   memset( &ge, 0, sizeof( GLOBALENTRY ) );
   ge.dwSize = sizeof( GLOBALENTRY );

   /* start the walk through the global heap */
   if ( !GlobalFirst( &ge, GLOBAL_ALL ) )
   {
      MessageBox( NULL, "GlobalFirst() Fails!", szAppName, errFlags );
      return NULL;
   }

   /* loop to process each entry of the global heap */
   do
   {
      /* first make sure this entry is even large enough for the SIB */
      if ( sizeof( WINSIB ) > ge.dwBlockSize )
         continue;

      /* make sure that this is an private (i.e. allocated) block */
      if ( GT_UNKNOWN != ge.wType )
         continue;

      /* make sure there is an actual memory block associated with this entry */
      if ( !ge.hBlock )
         continue;

      /* create a far pointer for accessing this entry */
      lpSIB = (LPWINSIB) GlobalLock( ge.hBlock );

      /* if this is our SIB block then return the pointer for it */
      if ( hInst == lpSIB->hi &&
               *(DWORD __far *) (lpSIB->sib.id) == *(DWORD *) "AZSB" )
         return lpSIB;

      /* unlock the entries memory block */
      GlobalUnlock( ge.hBlock );

   } while ( GlobalNext( &ge, GLOBAL_ALL ) );

   /* if we fell through to here we did not find the SIB */
   return NULL;
}
