790 lines
19 KiB
C
790 lines
19 KiB
C
//+----------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1996-1998
|
|
//
|
|
// File: prottest.c
|
|
//
|
|
// Contents: Test program for hydra licensing protocol
|
|
//
|
|
// History: 01-07-98 FredCh Created
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include <windows.h>
|
|
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
#include <limits.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "license.h"
|
|
#include "hslice.h"
|
|
#include "cryptkey.h"
|
|
#include "hccontxt.h"
|
|
#include "licecert.h"
|
|
#include "lscsp.h"
|
|
#include "sysapi.h"
|
|
|
|
#include "prottest.h"
|
|
|
|
#define MSG_SIZE 2048
|
|
|
|
BOOL
|
|
LsCsp_UnpackServerCert(
|
|
LPBYTE pbCert,
|
|
DWORD dwCertLen,
|
|
PHydra_Server_Cert pServerCert );
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
HANDLE g_hServerEvent = NULL, g_hClientEvent = NULL;
|
|
BYTE * pbServerMessage = NULL;
|
|
PBYTE ClientMessage;//[MSG_SIZE];
|
|
DWORD cbServerMessage = 0;
|
|
DWORD cbClientMessage;
|
|
LPBYTE g_pbPubKey = NULL;
|
|
DWORD g_cbPubKey = 0;
|
|
Hydra_Server_Cert g_ServerCertificate;
|
|
|
|
const BYTE g_abServerCertificate[184] = {
|
|
0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x5C, 0x00,
|
|
0x52, 0x53, 0x41, 0x31, 0x48, 0x00, 0x00, 0x00,
|
|
0x00, 0x02, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00,
|
|
0x01, 0x00, 0x01, 0x00, 0x83, 0x76, 0x5B, 0x09,
|
|
0x8F, 0xC1, 0x74, 0x12, 0x1B, 0xD3, 0x4E, 0x72,
|
|
0x72, 0x4D, 0xBE, 0xCE, 0x55, 0x1D, 0x29, 0x3D,
|
|
0x0E, 0xED, 0x28, 0x09, 0x50, 0x66, 0x32, 0xFA,
|
|
0x1D, 0xD2, 0xCC, 0x42, 0xDE, 0x5B, 0x4E, 0x3C,
|
|
0x35, 0xF6, 0x73, 0x5B, 0x0C, 0x0D, 0xB0, 0xA6,
|
|
0x4D, 0x76, 0xBA, 0xC0, 0x88, 0x5F, 0xC4, 0x67,
|
|
0x0B, 0xB8, 0xA3, 0x23, 0xA6, 0xC7, 0x79, 0xBD,
|
|
0x80, 0xD1, 0xA8, 0x75, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x48, 0x00,
|
|
0x19, 0x50, 0x2E, 0x2E, 0x82, 0xB4, 0xEB, 0xB3,
|
|
0x87, 0x85, 0xB9, 0x31, 0x4C, 0x29, 0x07, 0x05,
|
|
0xD7, 0x37, 0x99, 0x86, 0x15, 0x30, 0x56, 0xE4,
|
|
0x47, 0x7A, 0x2C, 0x2F, 0x4C, 0xBD, 0xF0, 0x37,
|
|
0xD3, 0x94, 0x01, 0xC8, 0x73, 0xEA, 0x5C, 0x2C,
|
|
0x3F, 0x60, 0x27, 0x1E, 0x5D, 0xA9, 0x54, 0x32,
|
|
0xDC, 0x49, 0xA4, 0x7E, 0x26, 0xAF, 0xEA, 0x07,
|
|
0xCA, 0x4E, 0xE9, 0x95, 0x8E, 0x66, 0xF0, 0x33,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
_stdcall
|
|
HydraServerThread();
|
|
|
|
void
|
|
_stdcall
|
|
HydraClientThread();
|
|
|
|
|
|
BOOL
|
|
TsIssueLicenseExpirationWarning(
|
|
LPDWORD lpdwDays,
|
|
PTS_LICENSE_INFO pTsLicenseInfo );
|
|
|
|
BOOL
|
|
FileTimeToUnixTime(
|
|
LPFILETIME pft,
|
|
time_t * t );
|
|
|
|
VOID
|
|
DisplayLicenseMessage(
|
|
DWORD dwDaysLeft );
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void _cdecl main(int argc, char *argv[])
|
|
{
|
|
DWORD ServerThreadID, ClientThreadID;
|
|
HANDLE ThreadHandles[2];
|
|
DWORD WaitStatus = 0;
|
|
Binary_Blob CertBlob;
|
|
LICENSE_STATUS Status;
|
|
DWORD dwFlag = CERT_DATE_DONT_VALIDATE;
|
|
//
|
|
// Create the server and client events
|
|
//
|
|
|
|
ThreadHandles[0] = NULL;
|
|
ThreadHandles[1] = NULL;
|
|
|
|
g_hServerEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
|
|
|
|
g_hClientEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
|
|
|
|
if( ( NULL == g_hServerEvent ) || ( NULL == g_hClientEvent ) )
|
|
{
|
|
printf( "Cannot create events\n" );
|
|
return;
|
|
}
|
|
|
|
InitializeLicenseLib( TRUE );
|
|
|
|
memset( &CertBlob, 0, sizeof( CertBlob ) );
|
|
|
|
//
|
|
// get the X509 certificate
|
|
//
|
|
|
|
Status = GetServerCertificate( CERT_TYPE_X509, &CertBlob, KEY_EXCHANGE_ALG_RSA );
|
|
|
|
if( LICENSE_STATUS_OK == Status )
|
|
{
|
|
Status = VerifyCertChain(
|
|
CertBlob.pBlob,
|
|
CertBlob.wBlobLen,
|
|
NULL,
|
|
&g_cbPubKey,
|
|
&dwFlag );
|
|
|
|
if( LICENSE_STATUS_INSUFFICIENT_BUFFER == Status )
|
|
{
|
|
g_pbPubKey = LocalAlloc( LPTR, g_cbPubKey );
|
|
|
|
if( NULL == g_pbPubKey )
|
|
{
|
|
goto done;
|
|
}
|
|
|
|
Status = VerifyCertChain( CertBlob.pBlob,
|
|
CertBlob.wBlobLen,
|
|
g_pbPubKey,
|
|
&g_cbPubKey,
|
|
&dwFlag );
|
|
}
|
|
|
|
if( LICENSE_STATUS_OK != Status )
|
|
{
|
|
printf( "Cannot verify X509 certificate chain: %x\n", Status );
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
//
|
|
// unpack the hardcoded certificate
|
|
//
|
|
|
|
if( !LsCsp_UnpackServerCert( ( LPBYTE )g_abServerCertificate, sizeof( g_abServerCertificate ),
|
|
&g_ServerCertificate ) )
|
|
{
|
|
printf( "cannot unpack server certificate\n" );
|
|
}
|
|
|
|
|
|
//
|
|
// Create the server and client threads
|
|
//
|
|
|
|
ThreadHandles[0] = CreateThread( NULL,
|
|
0,
|
|
( LPTHREAD_START_ROUTINE )HydraServerThread,
|
|
NULL,
|
|
0,
|
|
&ServerThreadID );
|
|
|
|
ThreadHandles[1] = CreateThread( NULL,
|
|
0,
|
|
( LPTHREAD_START_ROUTINE )HydraClientThread,
|
|
NULL,
|
|
0,
|
|
&ClientThreadID );
|
|
|
|
//
|
|
// wait for the server and client thread to die
|
|
//
|
|
|
|
WaitStatus = WaitForMultipleObjects( 2, ThreadHandles, TRUE, INFINITE );
|
|
|
|
//
|
|
// close the event handles
|
|
//
|
|
done:
|
|
|
|
if( g_hServerEvent )
|
|
{
|
|
CloseHandle( g_hServerEvent );
|
|
}
|
|
|
|
if( g_hClientEvent )
|
|
{
|
|
CloseHandle( g_hClientEvent );
|
|
}
|
|
|
|
if( ThreadHandles[0] )
|
|
{
|
|
CloseHandle( ThreadHandles[0] );
|
|
}
|
|
|
|
if( ThreadHandles[1] )
|
|
{
|
|
CloseHandle( ThreadHandles[1] );
|
|
}
|
|
|
|
ShutdownLicenseLib();
|
|
|
|
if( pbServerMessage )
|
|
{
|
|
LocalFree( pbServerMessage );
|
|
}
|
|
|
|
if( CertBlob.pBlob )
|
|
{
|
|
LocalFree( CertBlob.pBlob );
|
|
}
|
|
|
|
if( g_pbPubKey )
|
|
{
|
|
LocalFree( g_pbPubKey );
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
#define HYDRA_40_LICENSING_PROTOCOL_FLAG 0
|
|
#define HYDRA_40_LICENSING_PROTOCOL_VERSION LICENSE_PROTOCOL_VERSION_1_0 | PREAMBLE_VERSION_2_0
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
_stdcall
|
|
HydraServerThread()
|
|
{
|
|
LICENSE_STATUS Status;
|
|
HANDLE hContext = NULL;
|
|
LICENSE_CAPABILITIES LicenseCap;
|
|
TS_LICENSE_INFO
|
|
TsLicenseInfo;
|
|
|
|
Status = CreateLicenseContext( &hContext, LICENSE_CONTEXT_PER_SEAT );
|
|
|
|
if( LICENSE_STATUS_OK != Status )
|
|
{
|
|
printf( "HydraServerThread(): error creating license context\n" );
|
|
return;
|
|
}
|
|
|
|
memset( &LicenseCap, 0, sizeof( LicenseCap ) );
|
|
|
|
LicenseCap.KeyExchangeAlg = KEY_EXCHANGE_ALG_RSA;
|
|
|
|
#ifdef HYDRA_40_TEST
|
|
|
|
//
|
|
// talking to a Hydra 4.0 client
|
|
//
|
|
|
|
LicenseCap.ProtocolVer = HYDRA_40_LICENSING_PROTOCOL_VERSION;
|
|
LicenseCap.fAuthenticateServer = TRUE;
|
|
|
|
Status = InitializeLicenseContext(
|
|
hContext,
|
|
0,
|
|
&LicenseCap );
|
|
|
|
#else
|
|
|
|
#ifdef HYDRA_50_NO_SERVER_AUTHEN_X509
|
|
|
|
//
|
|
// talking to a Hydra 5.0 client and don't send certificate
|
|
//
|
|
|
|
LicenseCap.ProtocolVer = LICENSE_HIGHEST_PROTOCOL_VERSION;
|
|
LicenseCap.fAuthenticateServer = FALSE;
|
|
LicenseCap.CertType = CERT_TYPE_X509;
|
|
|
|
Status = InitializeLicenseContext(
|
|
hContext,
|
|
0,
|
|
&LicenseCap );
|
|
|
|
#else
|
|
|
|
#ifdef HYDRA_50_NO_SERVER_AUTHEN_PROPRIETORY
|
|
|
|
//
|
|
// talking to a Hydra 5.0 client and don't send certificate
|
|
//
|
|
|
|
LicenseCap.ProtocolVer = LICENSE_HIGHEST_PROTOCOL_VERSION;
|
|
LicenseCap.fAuthenticateServer = FALSE;
|
|
LicenseCap.CertType = CERT_TYPE_PROPRIETORY;
|
|
|
|
Status = InitializeLicenseContext(
|
|
hContext,
|
|
0,
|
|
&LicenseCap );
|
|
#else
|
|
|
|
//
|
|
// talking to a Hydra 5.0 client and also send certificate
|
|
//
|
|
|
|
LicenseCap.ProtocolVer = LICENSE_HIGHEST_PROTOCOL_VERSION;
|
|
LicenseCap.fAuthenticateServer = TRUE;
|
|
|
|
Status = InitializeLicenseContext(
|
|
hContext,
|
|
0,
|
|
&LicenseCap );
|
|
|
|
#endif // HYDRA_50_NO_SERVER_AUTHEN_X509
|
|
|
|
#endif // HYDRA_50_NO_SERVER_AUTHEN_PROPRIETORY
|
|
|
|
#endif // HYDRA_40_TEST
|
|
|
|
|
|
if( LICENSE_STATUS_OK != Status )
|
|
{
|
|
printf( "HydraServerThread(): cannot initialize license context: %x\n", Status );
|
|
goto done;
|
|
}
|
|
|
|
Status = AcceptLicenseContext( hContext,
|
|
0,
|
|
NULL,
|
|
&cbServerMessage,
|
|
&pbServerMessage );
|
|
|
|
|
|
while( LICENSE_STATUS_CONTINUE == Status )
|
|
{
|
|
SetEvent( g_hClientEvent );
|
|
|
|
WaitForSingleObject( g_hServerEvent, INFINITE );
|
|
|
|
if( pbServerMessage )
|
|
{
|
|
LocalFree( pbServerMessage );
|
|
pbServerMessage = NULL;
|
|
cbServerMessage = 0;
|
|
}
|
|
|
|
Status = AcceptLicenseContext( hContext,
|
|
cbClientMessage,
|
|
ClientMessage,
|
|
&cbServerMessage,
|
|
&pbServerMessage );
|
|
|
|
}
|
|
|
|
done:
|
|
|
|
if( hContext )
|
|
{
|
|
DWORD
|
|
dwDaysLeft = 0;
|
|
|
|
memset( &TsLicenseInfo, 0, sizeof( TsLicenseInfo ) );
|
|
|
|
Status = QueryLicenseInfo( hContext, &TsLicenseInfo );
|
|
|
|
if( LICENSE_STATUS_OK != Status )
|
|
{
|
|
printf( "HydraSeverThread: cannot query license info: %x\n", Status );
|
|
}
|
|
|
|
if( TsIssueLicenseExpirationWarning( &dwDaysLeft, &TsLicenseInfo ) )
|
|
{
|
|
DisplayLicenseMessage( dwDaysLeft );
|
|
}
|
|
|
|
FreeLicenseInfo( &TsLicenseInfo );
|
|
|
|
DeleteLicenseContext( hContext );
|
|
}
|
|
|
|
if( ( LICENSE_STATUS_ISSUED_LICENSE == Status ) ||
|
|
( LICENSE_STATUS_OK == Status ) )
|
|
{
|
|
//
|
|
// issueing a license or the license has been successfully validated
|
|
//
|
|
|
|
printf( "HydraServerThread: Protocol completed successfully\n" );
|
|
SetEvent( g_hClientEvent );
|
|
|
|
}
|
|
else if( LICENSE_STATUS_SEND_ERROR == Status )
|
|
{
|
|
printf( "HydraServerThread: sending error to client\n" );
|
|
SetEvent( g_hClientEvent );
|
|
|
|
}
|
|
else
|
|
{
|
|
printf( "HydraServerThread: protocol error: aborted\n" );
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
_stdcall
|
|
HydraClientThread()
|
|
{
|
|
LICENSE_STATUS Status;
|
|
HANDLE hContext;
|
|
|
|
|
|
#ifdef HYDRA_50_NO_SERVER_AUTHEN_X509
|
|
|
|
//
|
|
// no server authentication required. Use the public key in the
|
|
// X509 certificate
|
|
//
|
|
|
|
Status = LicenseInitializeContext(
|
|
&hContext,
|
|
LICENSE_CONTEXT_NO_SERVER_AUTHENTICATION );
|
|
|
|
if( LICENSE_STATUS_OK != Status )
|
|
{
|
|
printf( "Cannot initialize client context: %x\n", Status );
|
|
return;
|
|
}
|
|
|
|
//
|
|
// set the public key
|
|
//
|
|
|
|
Status = LicenseSetPublicKey(
|
|
hContext,
|
|
g_cbPubKey,
|
|
g_pbPubKey );
|
|
|
|
if( LICENSE_STATUS_OK != Status )
|
|
{
|
|
printf( "Cannot set public key: %x\n", Status );
|
|
goto done;
|
|
}
|
|
|
|
#else
|
|
|
|
#ifdef HYDRA_50_NO_SERVER_AUTHEN_PROPRIETORY
|
|
|
|
//
|
|
// no server authentication required. Use the proprietory certificate
|
|
//
|
|
|
|
Status = LicenseInitializeContext(
|
|
&hContext,
|
|
LICENSE_CONTEXT_NO_SERVER_AUTHENTICATION );
|
|
|
|
if( LICENSE_STATUS_OK != Status )
|
|
{
|
|
printf( "Cannot initialize client context: %x\n", Status );
|
|
return;
|
|
}
|
|
|
|
//
|
|
// set the proprietory certificate
|
|
//
|
|
|
|
Status = LicenseSetCertificate(
|
|
hContext,
|
|
&g_ServerCertificate );
|
|
|
|
if( LICENSE_STATUS_OK != Status )
|
|
{
|
|
printf( "cannot set certificate: %x\n", Status );
|
|
goto done;
|
|
}
|
|
|
|
#else
|
|
|
|
//
|
|
// hydra 4.0/5.0 licensing protocol.with certificate validation
|
|
//
|
|
|
|
Status = LicenseInitializeContext(
|
|
&hContext,
|
|
0 );
|
|
|
|
if( LICENSE_STATUS_OK != Status )
|
|
{
|
|
printf( "Cannot initialize client context: %x\n", Status );
|
|
return;
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
if( NULL == hContext )
|
|
{
|
|
printf( "HydraClientThread(): error creating license context\n" );
|
|
return;
|
|
}
|
|
|
|
if( LICENSE_STATUS_OK != Status )
|
|
{
|
|
printf( "HydraClientThread(): error setting certificate: %x\n", Status );
|
|
LicenseDeleteContext( hContext );
|
|
return;
|
|
}
|
|
|
|
|
|
WaitForSingleObject( g_hClientEvent, INFINITE );
|
|
|
|
cbClientMessage = 0;//MSG_SIZE;
|
|
|
|
if( LICENSE_STATUS_CONTINUE != (Status = LicenseAcceptContext( hContext,
|
|
0,
|
|
pbServerMessage,
|
|
cbServerMessage,
|
|
NULL,//ClientMessage,
|
|
&cbClientMessage )) )
|
|
{
|
|
printf("Error handling Server request\n");
|
|
return;
|
|
}
|
|
|
|
if( NULL == (ClientMessage = (PBYTE)GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT, cbClientMessage)) )
|
|
{
|
|
printf("Error allocating memory\n");
|
|
return;
|
|
}
|
|
|
|
//memset(ClientMessage, 0x00, cbClientMessage);
|
|
|
|
Status = LicenseAcceptContext(hContext,
|
|
0,
|
|
pbServerMessage,
|
|
cbServerMessage,
|
|
ClientMessage,
|
|
&cbClientMessage);
|
|
|
|
while( LICENSE_STATUS_CONTINUE == Status )
|
|
{
|
|
SetEvent( g_hServerEvent );
|
|
|
|
WaitForSingleObject( g_hClientEvent, INFINITE );
|
|
|
|
cbClientMessage = 0;
|
|
|
|
if(ClientMessage)
|
|
{
|
|
GlobalFree((HGLOBAL)ClientMessage);
|
|
ClientMessage = NULL;
|
|
}
|
|
|
|
Status = LicenseAcceptContext( hContext,
|
|
0,
|
|
pbServerMessage,
|
|
cbServerMessage,
|
|
NULL,//ClientMessage,
|
|
&cbClientMessage);
|
|
|
|
if( ( Status == LICENSE_STATUS_OK ) || ( Status != LICENSE_STATUS_CONTINUE ) )
|
|
{
|
|
break;
|
|
}
|
|
|
|
if( NULL == (ClientMessage = (PBYTE)GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT, cbClientMessage)) )
|
|
{
|
|
printf("Error allocating memory\n");
|
|
break;
|
|
}
|
|
|
|
memset(ClientMessage, 0x00, cbClientMessage);
|
|
|
|
Status = LicenseAcceptContext( hContext,
|
|
0,
|
|
pbServerMessage,
|
|
cbServerMessage,
|
|
ClientMessage,
|
|
&cbClientMessage );
|
|
|
|
|
|
}
|
|
|
|
done:
|
|
|
|
LicenseDeleteContext( hContext );
|
|
|
|
if( LICENSE_STATUS_OK == Status )
|
|
{
|
|
printf( "HydraClientThread: license protocol completed successfully\n" );
|
|
}
|
|
else
|
|
{
|
|
printf( "HydraClientThread: license protocol failed: 0x%x\n", Status );
|
|
}
|
|
|
|
if( ClientMessage )
|
|
{
|
|
GlobalFree( ( HGLOBAL )ClientMessage );
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
#define SECONDS_IN_A_DAY 86400 // number of seconds in a day
|
|
#define ISSUE_LICENSE_WARNING_PERIOD 150 // days to expiration when warning should be issued.
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
BOOL
|
|
TsIssueLicenseExpirationWarning(
|
|
LPDWORD lpdwDays,
|
|
PTS_LICENSE_INFO pTsLicenseInfo )
|
|
{
|
|
time_t
|
|
Expiration,
|
|
CurrentTime;
|
|
DWORD
|
|
dwDaysLeft;
|
|
|
|
if( NULL == pTsLicenseInfo )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
if( FALSE == pTsLicenseInfo->fTempLicense )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
//
|
|
// The client license is temporary, figure out how long more
|
|
// the license is valid
|
|
//
|
|
|
|
if( FALSE == FileTimeToUnixTime( &pTsLicenseInfo->NotAfter, &Expiration ) )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
time( &CurrentTime );
|
|
|
|
if( CurrentTime >= Expiration )
|
|
{
|
|
//
|
|
// license already expired
|
|
//
|
|
|
|
*lpdwDays = 0xFFFFFFFF;
|
|
return( TRUE );
|
|
}
|
|
|
|
dwDaysLeft = ( Expiration - CurrentTime ) / SECONDS_IN_A_DAY;
|
|
|
|
printf( "Number of days left for temporary license expiration: %d\n", dwDaysLeft );
|
|
|
|
if( ISSUE_LICENSE_WARNING_PERIOD >= dwDaysLeft )
|
|
{
|
|
*lpdwDays = dwDaysLeft;
|
|
return( TRUE );
|
|
}
|
|
|
|
return( FALSE );
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
BOOL
|
|
FileTimeToUnixTime(
|
|
LPFILETIME pft,
|
|
time_t * t )
|
|
{
|
|
SYSTEMTIME sysTime;
|
|
struct tm gmTime;
|
|
|
|
if( FileTimeToSystemTime( pft, &sysTime ) == FALSE )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
if( sysTime.wYear >= 2038 )
|
|
{
|
|
*t = INT_MAX;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Unix time support up to 2038/1/18
|
|
// restrict any expiration data
|
|
//
|
|
|
|
memset( &gmTime, 0, sizeof( gmTime ) );
|
|
gmTime.tm_sec = sysTime.wSecond;
|
|
gmTime.tm_min = sysTime.wMinute;
|
|
gmTime.tm_hour = sysTime.wHour;
|
|
gmTime.tm_year = sysTime.wYear - 1900;
|
|
gmTime.tm_mon = sysTime.wMonth - 1;
|
|
gmTime.tm_mday = sysTime.wDay;
|
|
|
|
*t = mktime( &gmTime );
|
|
}
|
|
|
|
return( *t != ( time_t )-1 );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
DisplayLicenseMessage(
|
|
DWORD dwDaysLeft )
|
|
{
|
|
TCHAR
|
|
szMsgCaption[512],
|
|
szMsgTitle[256];
|
|
HMODULE
|
|
hModule = GetModuleHandle( NULL );
|
|
LPDWORD
|
|
lpdw;
|
|
TCHAR
|
|
tszDays[ 10 ];
|
|
|
|
if( 0xFFFFFFFF == dwDaysLeft )
|
|
{
|
|
printf( "Temporary License has expired!\n" );
|
|
|
|
LoadString( hModule, STR_TEMP_LICENSE_EXPIRED_MSG, szMsgCaption, 512 );
|
|
}
|
|
else
|
|
{
|
|
printf( "%d days left before temporary license expires\n", dwDaysLeft );
|
|
|
|
//
|
|
// convert the number of days left to UNICODE character
|
|
//
|
|
|
|
_ultow( dwDaysLeft, tszDays, 10 );
|
|
lpdw = ( LPDWORD )&tszDays[0];
|
|
|
|
//
|
|
// prepare license about to expire message
|
|
//
|
|
|
|
LoadString( hModule, STR_TEMP_LICENSE_EXPIRATION_MSG, szMsgCaption, 512 );
|
|
|
|
FormatMessage(
|
|
FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
|
|
szMsgCaption,
|
|
0,
|
|
MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
|
|
( LPTSTR )szMsgCaption,
|
|
sizeof( szMsgCaption ),
|
|
( va_list * )&lpdw );
|
|
|
|
}
|
|
|
|
//
|
|
// prepare message title
|
|
//
|
|
|
|
LoadString( hModule, STR_TEMP_LICENSE_MSG_TITLE, szMsgTitle, 256 );
|
|
|
|
MessageBox( NULL, szMsgCaption, szMsgTitle, MB_OK );
|
|
|
|
return;
|
|
}
|