//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "MainUnit.h"

#include "../../../EnigmaSDK/Bcb/enigma_keygen_ide.h"
#pragma link "../../../EnigmaSDK/Bcb/keygen.lib"

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TfrmMain *frmMain;
//---------------------------------------------------------------------------
__fastcall TfrmMain::TfrmMain(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::cbHardwareClick(TObject *Sender)
{
  eHardware->Enabled = cbHardware->Checked;
}
//---------------------------------------------------------------------------

void __fastcall TfrmMain::FormShow(TObject *Sender)
{
  cbHardware->OnClick(cbHardware);
  cbExpiration->OnClick(cbExpiration);
  cbKeyFormat->ItemIndex = 2;
}
//---------------------------------------------------------------------------

void __fastcall TfrmMain::cbExpirationClick(TObject *Sender)
{
  dtpExpiration->Enabled = cbExpiration->Checked;
}
//---------------------------------------------------------------------------

void __fastcall TfrmMain::bCloseClick(TObject *Sender)
{
  Application->Terminate();
}
//---------------------------------------------------------------------------

void __fastcall TfrmMain::bGenClick(TObject *Sender)
{
  GenKeyParams kp;
  BYTE keybuffer[255];
  WORD wYear;
  WORD wDay;
  WORD wMonth;
  DWORD dwResult;

  mKey->Clear();

  // Clear params buffer
  memset(&kp, 0, sizeof(kp));

  if (rbLongKeys->Checked)
  {
    kp.KeyType = KEY_TYPE_LONG;
  }
  if (rbShortKeys->Checked)
  {
    kp.KeyType = KEY_TYPE_SHORT;
  }
  switch (cbKeyFormat->ItemIndex)
  {
    case 0:
    {
      kp.KeyFormat = KEY_FORMAT_10;
      break;
    }
    case 1:
    {
      kp.KeyFormat = KEY_FORMAT_16;
      break;
    }
    case 2:
    {
      kp.KeyFormat = KEY_FORMAT_32;
      break;
    }
    case 3:
    {
      kp.KeyFormat = KEY_FORMAT_64;
      break;
    }
    default:
    {
      kp.KeyFormat = KEY_FORMAT_32;
      break;
    }
  }

  // Fill key buffer
  memset(&keybuffer, 0, sizeof(keybuffer));
  kp.Key = (char*) keybuffer;
  kp.KeyLen = sizeof(keybuffer);

  // Fill User Info
  kp.RegInfo = eUserInfo->Text.c_str();
  kp.RegInfoLen = strlen(kp.RegInfo);

  // Key expiration info
  kp.UseKeyExpiration = (BYTE)cbExpiration->Checked;
  DecodeDate(dtpExpiration->DateTime, wYear, wMonth, wDay);
  kp.ExpirationYear = wYear;
  kp.ExpirationMonth = wMonth;
  kp.ExpirationDay = wDay;

  // Hardware ID
  kp.UseHardwareLocking = (BYTE)cbHardware->Checked;
  kp.HardwareID = (char*)eHardware->Text.c_str();

  // Crypt Sections
  kp.EncryptedSections[0] = (BYTE)cbSection1->Checked;
  kp.EncryptedSections[1] = (BYTE)cbSection2->Checked;
  kp.EncryptedSections[2] = (BYTE)cbSection3->Checked;
  kp.EncryptedSections[3] = (BYTE)cbSection4->Checked;
  kp.EncryptedSections[4] = (BYTE)cbSection5->Checked;
  kp.EncryptedSections[5] = (BYTE)cbSection6->Checked;
  kp.EncryptedSections[6] = (BYTE)cbSection7->Checked;
  kp.EncryptedSections[7] = (BYTE)cbSection8->Checked;
  kp.EncryptedSections[8] = (BYTE)cbSection9->Checked;
  kp.EncryptedSections[9] = (BYTE)cbSection10->Checked;
  kp.EncryptedSections[10] = (BYTE)cbSection11->Checked;
  kp.EncryptedSections[11] = (BYTE)cbSection12->Checked;
  kp.EncryptedSections[12] = (BYTE)cbSection13->Checked;
  kp.EncryptedSections[13] = (BYTE)cbSection14->Checked;
  kp.EncryptedSections[14] = (BYTE)cbSection15->Checked;
  kp.EncryptedSections[15] = (BYTE)cbSection16->Checked;

  // Secure constant (get it from project file)!
  // or use special utility
  if (kp.KeyType == KEY_TYPE_LONG)
  {
    kp.D = "3K4RHBXV93J75R72XBF68M5GTQ2PDDVCJCQ9ZZ7CXBZYJNY6ASWVB6S3X4JP9TWPBANMW2HSMPAZ7GY5WZF8TQYJ36VUQZQ7J4F6JF";
    kp.N = "7MSYMACUVPSKBB44WSEF3Q7T6ATNEDQ9D3UGQRP8SYVCXDDEX8TB78PFHWXGR4RVVTWVCSXANQWHDLWF2XTMS7PAA3396RALRP3UUK";
  }
  if (kp.KeyType == KEY_TYPE_SHORT)
  {
    kp.D = "9A2GSDM7LGTE5TLDR74QRTH8SSC76XZGD5SLHMHP";
    kp.N = "3RK8BPE4MW9NFJARVTFWMGFSWJCJMMZ7G5XK97JJM";
  }
  kp.A = "F4A190D21E05F4DF387A18CFBB70426E";
  kp.B = "C7A44A94C94D7F290037E9DACCC2CB23";

  // Generate reg. key
  dwResult = KG_GenerateRegistrationKey(&kp);

  if (dwResult == ERROR_OK)
  {
    mKey->Text = (AnsiString)kp.Key;
  } else
  {
    switch (dwResult)
    {
      case ERROR_KEY_BUFFER_NOT_ALLOCATED:
        mKey->Text = "ERROR_KEY_BUFFER_NOT_ALLOCATED";
        break;
      case ERROR_KEY_BUFFER_LESS:
        mKey->Text = "ERROR_KEY_BUFFER_LESS";
        break;
      case ERROR_REGINFO_BUFFER_NOT_ALLOCATED:
        mKey->Text = "ERROR_REGINFO_BUFFER_NOT_ALLOCATED";
        break;
      case ERROR_REGINFO_BUFFER_EMPTY:
        mKey->Text = "ERROR_REGINFO_BUFFER_EMPTY";
        break;
      case ERROR_HARDWARE_TYPE_UNKNOWN:
        mKey->Text = "ERROR_HARDWARE_TYPE_UNKNOWN";
        break;
      case ERROR_HARDWARE_ID:
        mKey->Text = "ERROR_HARDWARE_ID";
        break;
      case ERROR_HARDWARE_BUFFER_NOT_ALLOCATED:
        mKey->Text = "ERROR_HARDWARE_BUFFER_NOT_ALLOCATED";
        break;
      case ERROR_HARDWARE_BUFFER_EMPTY:
        mKey->Text = "ERROR_HARDWARE_BUFFER_EMPTY";
        break;
      case ERROR_INVALID_CONSTANT_D:
        mKey->Text = "ERROR_INVALID_CONSTANT_D";
        break;
      case ERROR_INVALID_CONSTANT_N:
        mKey->Text = "ERROR_INVALID_CONSTANT_N";
        break;
      case ERROR_INVALID_CONSTANT_A:
        mKey->Text = "ERROR_INVALID_CONSTANT_A";
        break;
      case ERROR_INVALID_CONSTANT_B:
        mKey->Text = "ERROR_INVALID_CONSTANT_B";
        break;
      case ERROR_PROJECT_FILE_NOT_FOUND:
        mKey->Text = "ERROR_PROJECT_FILE_NOT_FOUND";
        break;
      case ERROR_PROJECT_FILE_INVALID:
        mKey->Text = "ERROR_PROJECT_FILE_INVALID";
        break;
      default:
        mKey->Text = "ERROR_UNKNOWN";
        break;
    }
  };
}
//---------------------------------------------------------------------------

void __fastcall TfrmMain::bGenFPClick(TObject *Sender)
{
  GenKeyParams kp;
  BYTE keybuffer[255];
  WORD wYear;
  WORD wDay;
  WORD wMonth;
  DWORD dwResult;
  AnsiString FileName;

  mKey->Clear();

  // Clear params buffer
  memset(&kp, 0, sizeof(kp));

  // Fill key buffer
  memset(&keybuffer, 0, sizeof(keybuffer));
  kp.Key = (char*) keybuffer;
  kp.KeyLen = sizeof(keybuffer);

  // Fill User Info
  kp.RegInfo = eUserInfo->Text.c_str();
  kp.RegInfoLen = strlen(kp.RegInfo);

  // Key expiration info
  kp.UseKeyExpiration = (BYTE)cbExpiration->Checked;
  DecodeDate(dtpExpiration->DateTime, wYear, wMonth, wDay);
  kp.ExpirationYear = wYear;
  kp.ExpirationMonth = wMonth;
  kp.ExpirationDay = wDay;

  // Hardware ID
  kp.UseHardwareLocking = (BYTE)cbHardware->Checked;
  kp.HardwareID = (char*)eHardware->Text.c_str();

  // Crypt Sections
  kp.EncryptedSections[0] = (BYTE)cbSection1->Checked;
  kp.EncryptedSections[1] = (BYTE)cbSection2->Checked;
  kp.EncryptedSections[2] = (BYTE)cbSection3->Checked;
  kp.EncryptedSections[3] = (BYTE)cbSection4->Checked;
  kp.EncryptedSections[4] = (BYTE)cbSection5->Checked;
  kp.EncryptedSections[5] = (BYTE)cbSection6->Checked;
  kp.EncryptedSections[6] = (BYTE)cbSection7->Checked;
  kp.EncryptedSections[7] = (BYTE)cbSection8->Checked;
  kp.EncryptedSections[8] = (BYTE)cbSection9->Checked;
  kp.EncryptedSections[9] = (BYTE)cbSection10->Checked;
  kp.EncryptedSections[10] = (BYTE)cbSection11->Checked;
  kp.EncryptedSections[11] = (BYTE)cbSection12->Checked;
  kp.EncryptedSections[12] = (BYTE)cbSection13->Checked;
  kp.EncryptedSections[13] = (BYTE)cbSection14->Checked;
  kp.EncryptedSections[14] = (BYTE)cbSection15->Checked;
  kp.EncryptedSections[15] = (BYTE)cbSection16->Checked;

  FileName = IncludeTrailingBackslash(ExtractFilePath(Application->ExeName)) + "default.enigma";

  // Generate reg. key
  dwResult = KG_GenerateRegistrationKeyFromProject(FileName.c_str(), &kp);

  if (dwResult == ERROR_OK)
  {
    mKey->Text = (AnsiString)kp.Key;
  } else
  {
    switch (dwResult)
    {
      case ERROR_KEY_BUFFER_NOT_ALLOCATED:
        mKey->Text = "ERROR_KEY_BUFFER_NOT_ALLOCATED";
        break;
      case ERROR_KEY_BUFFER_LESS:
        mKey->Text = "ERROR_KEY_BUFFER_LESS";
        break;
      case ERROR_REGINFO_BUFFER_NOT_ALLOCATED:
        mKey->Text = "ERROR_REGINFO_BUFFER_NOT_ALLOCATED";
        break;
      case ERROR_REGINFO_BUFFER_EMPTY:
        mKey->Text = "ERROR_REGINFO_BUFFER_EMPTY";
        break;
      case ERROR_HARDWARE_TYPE_UNKNOWN:
        mKey->Text = "ERROR_HARDWARE_TYPE_UNKNOWN";
        break;
      case ERROR_HARDWARE_ID:
        mKey->Text = "ERROR_HARDWARE_ID";
        break;
      case ERROR_HARDWARE_BUFFER_NOT_ALLOCATED:
        mKey->Text = "ERROR_HARDWARE_BUFFER_NOT_ALLOCATED";
        break;
      case ERROR_HARDWARE_BUFFER_EMPTY:
        mKey->Text = "ERROR_HARDWARE_BUFFER_EMPTY";
        break;
      case ERROR_INVALID_CONSTANT_D:
        mKey->Text = "ERROR_INVALID_CONSTANT_D";
        break;
      case ERROR_INVALID_CONSTANT_N:
        mKey->Text = "ERROR_INVALID_CONSTANT_N";
        break;
      case ERROR_INVALID_CONSTANT_A:
        mKey->Text = "ERROR_INVALID_CONSTANT_A";
        break;
      case ERROR_INVALID_CONSTANT_B:
        mKey->Text = "ERROR_INVALID_CONSTANT_B";
        break;
      case ERROR_PROJECT_FILE_NOT_FOUND:
        mKey->Text = "ERROR_PROJECT_FILE_NOT_FOUND";
        break;
      case ERROR_PROJECT_FILE_INVALID:
        mKey->Text = "ERROR_PROJECT_FILE_INVALID";
        break;
      default:
        mKey->Text = "ERROR_UNKNOWN";
        break;
    }
  };
}
//---------------------------------------------------------------------------

