/*******************************************/
/* VMX Installer Custom Edition main       */
/*******************************************/
/* Программа - инсталлятор с поддержкой    */
/* настройки внешнего вида и защиты архива */
/* Использован алгоритм VMX FaCrypt 1.0    */
/* (шифровка с помощью перестановки по     */
/*   матрице факториалов)                  */
/*                                         */
/* VV   VV        MM     MM        XX   XX */
/* VV   VV        MMMM MMMM         XX XX  */
/* VV   VV        MM MMM MM          XXX   */
/*  VV VV         MM  M  MM         XX XX  */
/*   VVV          MM     MM        XX   XX */
/*               (c) Виталий Филиппов 2003 */
/*******************************************/

//---------------------------------------------------------------------------
// Height
#include <vcl.h>
#pragma hdrstop

#include "smain.h"
#include <stdio.h>
#include "splash.h"
#include <shlobj.hpp>
#include <registry.hpp>
#include "vsuwin.h"
//#define __DEBUG__
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "VmxCustomBtn"
#pragma link "VmxAlphaImage"
#pragma link "SetupSideBar"
#pragma link "VmxCustomProgress"
#pragma link "VmxCustomCheck"
#pragma link "VmxLabel"
#pragma link "VmxCustomScrollbar"
#pragma link "VmxCustomTreeView"
#pragma link "VmxXPBitBtn"
#pragma resource "*.dfm"
TMainForm *MainForm;
AnsiString mTempDir;
//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

AnsiString FindFile (AnsiString Dir, AnsiString File)
{
  TSearchRec sr;
  if (FindFirst (Dir+"*.*",faAnyFile|faDirectory,sr)==0)
  {
    int a = sr.Attr&faDirectory;
    if (a>0&&sr.Name!=".."&&sr.Name!=".")
    {
      AnsiString B = FindFile (Dir+sr.Name+"\\",File);
      if (B != "NOTFOUND")
        return B;
    }
    else if (sr.Name==File)
    {
      AnsiString A = Dir + File;
      FindClose (sr);
      return A;
    }
    while (FindNext (sr)==0)
    {
      int a = sr.Attr&faDirectory;
      if (a>0&&sr.Name!=".."&&sr.Name!=".")
      {
        AnsiString B = FindFile (Dir+sr.Name+"\\",File);
        if (B != "NOTFOUND")
          return B;
      }
      else if (sr.Name==File)
      {
        AnsiString A = Dir + File;
        FindClose (sr);
        return A;
      }
    }
  }
  FindClose (sr);
  return "NOTFOUND";
}

AnsiString __fastcall GetNewTempDir (void)
{
  GUID a;
  CoInitialize (NULL);
  CoCreateGuid (&a);
  CoUninitialize ();
  return ("C:\\TEMP\\VMXINSTALLER.TMP."+GUIDToString(a)+"\\");
}

enum TInsScreen
{
  isHi, isLicense, isSelectType, isPassword, isSelFeat, isSelDir, isSelShortDir, isNext, isFinished
};

TInsScreen CurScr = isHi;

// код распаковки и самораспаковки {

AnsiString StreamString (TFileStream *fs)
{
  char c;
  fs->Read(&c,1);
  AnsiString A;
  while (c!='\n'&&c!='\r'&&c!='\0'&&fs->Position!=fs->Size)
  {
    A+=c;
    fs->Read(&c,1);
  }
  return A;
}

__int64 CompiledSize = 377344;

bool __fastcall SelfExtractAll (AnsiString Dir)
{
  TFileStream *fs = new TFileStream (Application->ExeName,fmOpenRead);
  if (fs->Size==CompiledSize)
  {
    delete fs;
    return false;
  }
  fs->Seek(CompiledSize,soBeginning);
  char sign [4];
  fs->Read(sign,3);
  sign [3] = '\0';
  if (AnsiString (sign)!="VSM")
  {
    delete fs;
    Application -> MessageBox ("Пакет повреждён. Установка невозможна", "Ошибка", MB_OK|MB_ICONSTOP);
    Application->Terminate();
    return false;
  }
  int n;
  fs->Read(&n,4);
  __int64 *sizes = new __int64 [n];
  __int64 alls = 0;
  for (int i = 0; i < n; i++)
  {
    fs->Read(&sizes[i],8);
    alls+=sizes[i];
  }
  AnsiString *names = new AnsiString [n];
  for (int i = 0; i < n; i++)
    names [i] = StreamString (fs);
  TFileStream *f2;
  __int64 comps = 0;
  SplashForm->Show();
  Application->ProcessMessages();
  for (int i = 0; i < n; i++)
  {
    f2 = new TFileStream (Dir+names[i],fmCreate|fmOpenWrite);
    f2 -> Position = 0;
    f2 -> CopyFrom (fs, sizes[i]);
    comps+=sizes[i];
    SplashForm->Progr=comps*100/alls;
    //SplashForm->Reset=false;
    SplashForm->PaintBox1Paint(NULL);
    Application->ProcessMessages();
    delete f2;
  }
  SplashForm->Close();
  Application->ProcessMessages();
  delete [] names;
  delete [] sizes;
  delete fs;
  return true;
}

void __fastcall SelfCleanup (AnsiString Dir)
{
  TFileStream *fs = new TFileStream (Application->ExeName,fmOpenRead);
  if (fs->Size==CompiledSize)
  {
    delete fs;
    return;
  }
  fs->Seek(CompiledSize,soBeginning);
  char sign [4];
  fs->Read(sign,3);
  sign [3] = '\0';
  if (AnsiString (sign)!="VSM")
  {
    delete fs;
    return;
  }
  int n;
  fs->Read(&n,4);
  __int64 *sizes = new __int64 [n];
  for (int i = 0; i < n; i++)
    fs->Read(&sizes[i],8);
  AnsiString *names = new AnsiString [n];
  for (int i = 0; i < n; i++)
    names [i] = StreamString (fs);
  for (int i = 0; i < n; i++)
    remove ((Dir+names[i]).c_str());
  delete [] names;
  delete [] sizes;
  delete fs;
}

bool __fastcall ExtractAll (AnsiString Dir)
{
  TFileStream *fs = new TFileStream (ParamStr(1),fmOpenRead);
  char sign [4];
  fs->Read(sign,3);
  sign [3] = '\0';
  if (AnsiString (sign)!="VSM")
  {
    delete fs;
    Application -> MessageBox ("Пакет повреждён. Установка невозможна", "Ошибка", MB_OK|MB_ICONSTOP);
    return false;
  }
  int n;
  fs->Read(&n,4);
  __int64 *sizes = new __int64 [n];
  __int64 alls = 0;
  for (int i = 0; i < n; i++)
  {
    fs->Read(&sizes[i],8);
    alls+=sizes[i];
  }
  AnsiString *names = new AnsiString [n];
  for (int i = 0; i < n; i++)
    names [i] = StreamString (fs);
  TFileStream *f2;
  __int64 comps = 0;
  SplashForm->Show();
  Application->ProcessMessages();
  for (int i = 0; i < n; i++)
  {
    f2 = new TFileStream (Dir+names[i],fmCreate|fmOpenWrite);
    f2 -> Position = 0;
    f2 -> CopyFrom (fs, sizes[i]);
    comps+=sizes[i];
    //SplashForm->Reset=false;
    SplashForm->Progr=comps*100/alls;
    SplashForm->PaintBox1Paint(NULL);
    Application->ProcessMessages();
    delete f2;
  }
  SplashForm->Close();
  Application->ProcessMessages();
  delete [] names;
  delete [] sizes;
  delete fs;
  return true;
}

void __fastcall Cleanup (AnsiString Dir)
{
  TFileStream *fs = new TFileStream (ParamStr(1),fmOpenRead);
  char sign [4];
  fs->Read(sign,3);
  sign [3] = '\0';
  if (AnsiString (sign)!="VSM")
  {
    delete fs;
    return;
  }
  int n;
  fs->Read(&n,4);
  __int64 *sizes = new __int64 [n];
  for (int i = 0; i < n; i++)
    fs->Read(&sizes[i],8);
  AnsiString *names = new AnsiString [n];
  for (int i = 0; i < n; i++)
    names [i] = StreamString (fs);
  for (int i = 0; i < n; i++)
    remove ((Dir+names[i]).c_str());
  delete [] names;
  delete [] sizes;
  delete fs;
}

AnsiString RS (FILE *fp)
{
  AnsiString A;
  char c = fgetc (fp);
  while (c != '\n' && c != '\r' && c != '\0' && !feof(fp))
  {
    A+=c;
    c=fgetc(fp);
  }
  return A;
}

// } код распаковки и самораспаковки


// HEXFILE {

void __fastcall HexToFile (AnsiString FI, AnsiString FO)
{
  TFileStream *fi = new TFileStream (FI,fmOpenRead);
  TFileStream *fo = new TFileStream (FO,fmOpenWrite|fmCreate);
  fo->Position=0;
  BYTE b;
  AnsiString H;
  char c[2];
  while (fi->Position!=fi->Size)
  {
    fi->Read(&c[0],1);
    fi->Read(&c[1],1);
    H = AnsiString (c[0]) + AnsiString (c[1]);
    b = StrToInt ("0x"+H);
    fo->Write(&b,1);
  }
  delete fi;
  delete fo;
}

// } HEXFILE

// Ignore \n \r code {

void __fastcall ignore (AnsiString FI, AnsiString FO)
{
  FILE *fp = fopen (FI.c_str(),"r");
  FILE *f2 = fopen (FO.c_str(),"w");
  char c;
  while (!feof(fp))
  {
    c = fgetc (fp);
    if (feof(fp))
      break;
    if (c != '\n' && c != '\r' && c != '\0')
      fputc (c, f2);
  }
  fclose (fp);
  fclose (f2);
}

// } Ignore \n \r code

// VMX Factorial code - 4 (only decrypt) {

union TBC
{
  BYTE bt;
  bool bit0:1;
  bool bit1:1;
  bool bit2:1;
  bool bit3:1;
  bool bit4:1;
  bool bit5:1;
  bool bit6:1;
  bool bit7:1;
};

class TByteCode
{
  public:
    union
    {
      BYTE bt;
      struct
      {
        bool bit0:1;
        bool bit1:1;
        bool bit2:1;
        bool bit3:1;
        bool bit4:1;
        bool bit5:1;
        bool bit6:1;
        bool bit7:1;
      };
    };
    TByteCode ()
    {
      bit0=false;
      bit1=false;
      bit2=false;
      bit3=false;
      bit4=false;
      bit5=false;
      bit6=false;
      bit7=false;
    }
    bool __fastcall GetBit (int Index)
    {
      switch (Index)
      {
        case 0: return bit0;
        case 1: return bit1;
        case 2: return bit2;
        case 3: return bit3;
        case 4: return bit4;
        case 5: return bit5;
        case 6: return bit6;
        case 7: return bit7;
        default: return false;
      }
    };
    void __fastcall SetBit (int Index, bool New)
    {
      switch (Index)
      {
        case 0: bit0=New; break;
        case 1: bit1=New; break;
        case 2: bit2=New; break;
        case 3: bit3=New; break;
        case 4: bit4=New; break;
        case 5: bit5=New; break;
        case 6: bit6=New; break;
        case 7: bit7=New; break;
      }
    }
    __property bool bits [int Index] = {read = GetBit, write = SetBit};
    //__property BYTE bt = {read = data.bt, write = data.bt};
};

union TWC
{
  struct
  {
  BYTE byte0;
  BYTE byte1;
  };
  short i;
  struct
  {
  bool bit0:1;
  bool bit1:1;
  bool bit2:1;
  bool bit3:1;
  bool bit4:1;
  bool bit5:1;
  bool bit6:1;
  bool bit7:1;
  bool bit8:1;
  bool bit9:1;
  bool bit10:1;
  bool bit11:1;
  bool bit12:1;
  bool bit13:1;
  bool bit14:1;
  bool bit15:1;
  };
};

class TWordCode
{
  public:
    TWC data;
    TWordCode ()
    {
      data.bit0=false;
      data.bit1=false;
      data.bit2=false;
      data.bit3=false;
      data.bit4=false;
      data.bit5=false;
      data.bit6=false;
      data.bit7=false;
      data.bit8=false;
      data.bit9=false;
      data.bit10=false;
      data.bit11=false;
      data.bit12=false;
      data.bit13=false;
      data.bit14=false;
      data.bit15=false;
    }
    bool __fastcall GetBit (int Index)
    {
      switch (Index)
      {
        case 0: return data.bit0;
        case 1: return data.bit1;
        case 2: return data.bit2;
        case 3: return data.bit3;
        case 4: return data.bit4;
        case 5: return data.bit5;
        case 6: return data.bit6;
        case 7: return data.bit7;
        case 8: return data.bit8;
        case 9: return data.bit9;
        case 10: return data.bit10;
        case 11: return data.bit11;
        case 12: return data.bit12;
        case 13: return data.bit13;
        case 14: return data.bit14;
        case 15: return data.bit15;
        default: return false;
      }
    };
    void __fastcall SetBit (int Index, bool New)
    {
      switch (Index)
      {
        case 0: data.bit0=New; break;
        case 1: data.bit1=New; break;
        case 2: data.bit2=New; break;
        case 3: data.bit3=New; break;
        case 4: data.bit4=New; break;
        case 5: data.bit5=New; break;
        case 6: data.bit6=New; break;
        case 7: data.bit7=New; break;
        case 8: data.bit8=New; break;
        case 9: data.bit9=New; break;
        case 10: data.bit10=New; break;
        case 11: data.bit11=New; break;
        case 12: data.bit12=New; break;
        case 13: data.bit13=New; break;
        case 14: data.bit14=New; break;
        case 15: data.bit15=New; break;
      }
    }
    __property bool bits [int Index] = {read = GetBit, write = SetBit};
    __property short DatI = {read = data.i, write = data.i};
};

struct TFa4Matrix
{
  bool bits[24][8];
};

union TIC
{
  int I;
  struct
  {
  bool bit0:1;
  bool bit1:1;
  bool bit2:1;
  bool bit3:1;
  bool bit4:1;
  bool bit5:1;
  bool bit6:1;
  bool bit7:1;
  bool bit8:1;
  bool bit9:1;
  bool bit10:1;
  bool bit11:1;
  bool bit12:1;
  bool bit13:1;
  bool bit14:1;
  bool bit15:1;
  bool bit16:1;
  bool bit17:1;
  bool bit18:1;
  bool bit19:1;
  bool bit20:1;
  bool bit21:1;
  bool bit22:1;
  bool bit23:1;
  bool bit24:1;
  bool bit25:1;
  bool bit26:1;
  bool bit27:1;
  bool bit28:1;
  bool bit29:1;
  bool bit30:1;
  bool bit31:1;
  };
};

class TIntCode
{
  public:
    TIC data;
    TIntCode ()
    {
      data.bit0=false;
      data.bit1=false;
      data.bit2=false;
      data.bit3=false;
      data.bit4=false;
      data.bit5=false;
      data.bit6=false;
      data.bit7=false;
      data.bit8=false;
      data.bit9=false;
      data.bit10=false;
      data.bit11=false;
      data.bit12=false;
      data.bit13=false;
      data.bit14=false;
      data.bit15=false;
      data.bit16=false;
      data.bit17=false;
      data.bit18=false;
      data.bit19=false;
      data.bit20=false;
      data.bit21=false;
      data.bit22=false;
      data.bit23=false;
      data.bit24=false;
      data.bit25=false;
      data.bit26=false;
      data.bit27=false;
      data.bit28=false;
      data.bit29=false;
      data.bit30=false;
      data.bit31=false;
    }
    bool __fastcall GetBit (int Index)
    {
      switch (Index)
      {
        case 0: return data.bit0;
        case 1: return data.bit1;
        case 2: return data.bit2;
        case 3: return data.bit3;
        case 4: return data.bit4;
        case 5: return data.bit5;
        case 6: return data.bit6;
        case 7: return data.bit7;
        case 8: return data.bit8;
        case 9: return data.bit9;
        case 10: return data.bit10;
        case 11: return data.bit11;
        case 12: return data.bit12;
        case 13: return data.bit13;
        case 14: return data.bit14;
        case 15: return data.bit15;
        case 16: return data.bit16;
        case 17: return data.bit17;
        case 18: return data.bit18;
        case 19: return data.bit19;
        case 20: return data.bit20;
        case 21: return data.bit21;
        case 22: return data.bit22;
        case 23: return data.bit23;
        case 24: return data.bit24;
        case 25: return data.bit25;
        case 26: return data.bit26;
        case 27: return data.bit27;
        case 28: return data.bit28;
        case 29: return data.bit29;
        case 30: return data.bit30;
        case 31: return data.bit31;
        default: return false;
      }
    }
    void __fastcall SetBit (int Index, bool New)
    {
      switch (Index)
      {
        case 0: data.bit0=New; break;
        case 1: data.bit1=New; break;
        case 2: data.bit2=New; break;
        case 3: data.bit3=New; break;
        case 4: data.bit4=New; break;
        case 5: data.bit5=New; break;
        case 6: data.bit6=New; break;
        case 7: data.bit7=New; break;
        case 8: data.bit8=New; break;
        case 9: data.bit9=New; break;
        case 10: data.bit10=New; break;
        case 11: data.bit11=New; break;
        case 12: data.bit12=New; break;
        case 13: data.bit13=New; break;
        case 14: data.bit14=New; break;
        case 15: data.bit15=New; break;
        case 16: data.bit16=New; break;
        case 17: data.bit17=New; break;
        case 18: data.bit18=New; break;
        case 19: data.bit19=New; break;
        case 20: data.bit20=New; break;
        case 21: data.bit21=New; break;
        case 22: data.bit22=New; break;
        case 23: data.bit23=New; break;
        case 24: data.bit24=New; break;
        case 25: data.bit25=New; break;
        case 26: data.bit26=New; break;
        case 27: data.bit27=New; break;
        case 28: data.bit28=New; break;
        case 29: data.bit29=New; break;
        case 30: data.bit30=New; break;
        case 31: data.bit31=New; break;
      }
    }
    __property bool bits [int Index] = {read = GetBit, write = SetBit};
    __property int I = {read = data.I, write = data.I};
};

TByteCode __fastcall DecryptByte (TWordCode A, TFa4Matrix Mat)
{
  TIntCode N;
  N.bits[0]=A.bits[8];
  N.bits[1]=A.bits[9];
  N.bits[2]=A.bits[10];
  N.bits[3]=A.bits[11];
  N.bits[4]=A.bits[12];
  TIntCode ns[4];
  ns[0].bits[0]=Mat.bits[N.I][0];
  ns[0].bits[1]=Mat.bits[N.I][1];
  ns[1].bits[0]=Mat.bits[N.I][2];
  ns[1].bits[1]=Mat.bits[N.I][3];
  ns[2].bits[0]=Mat.bits[N.I][4];
  ns[2].bits[1]=Mat.bits[N.I][5];
  ns[3].bits[0]=Mat.bits[N.I][6];
  ns[3].bits[1]=Mat.bits[N.I][7];
  TByteCode x;
  for (int i = 0; i < 4; i++)
  {
    x.bits[ns[i].I*2]=A.bits[i*2];
    x.bits[ns[i].I*2+1]=A.bits[i*2+1];
  }
  return x;
}

TFa4Matrix LoadMatrix (AnsiString File)
{
  TFa4Matrix a;
  TFileStream *fs = new TFileStream (File,fmOpenRead);
  TByteCode A;
  for (int i = 0; i < 24; i++)
  {
    fs->Read(&A.bt,1);
    for (int j = 0; j < 8; j++)
      a.bits[i][j]=A.bits[j];
  }
  delete fs;
  return a;
}

AnsiString __fastcall DecodeFileIntoString (AnsiString File, AnsiString Matrix)
{
  TFa4Matrix m = LoadMatrix (Matrix);
  TByteCode x;
  TWordCode a;
  AnsiString Out;
  TFileStream *fs = new TFileStream (File,fmOpenRead);
  while (fs->Position!=fs->Size)
  {
    fs->Read(&a.data.byte0,1);
    fs->Read(&a.data.byte1,1);
    x = DecryptByte (a, m);
    Out=Out+AnsiString ((char)x.bt);
  }
  delete fs;
  return Out;
}

// } FACRYPT

void __fastcall TMainForm::CloseBtnClick(TObject *Sender)
{
  Close ();
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::MinimizeBtnClick(TObject *Sender)
{
  Application->Minimize();
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::DragCaptionMouseDown(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
  ReleaseCapture ();
  SNDMSG (Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);        
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormShow(TObject *Sender)
{
  Wit1L->Caption = "Вас приветствует VMX Installer - программа,\n\rкоторая поможет Вам произвести установку";
  LCMemo->Lines->SaveToFile(ExtractFilePath(ParamStr(0))+"lca.tmp");
  LAMemo->Lines->SaveToFile(ExtractFilePath(ParamStr(0))+"laa.tmp");
  LFMemo->Lines->SaveToFile(ExtractFilePath(ParamStr(0))+"lfa.tmp");
  ignore (ExtractFilePath(ParamStr(0))+"lca.tmp",ExtractFilePath(ParamStr(0))+"lch.tmp");
  ignore (ExtractFilePath(ParamStr(0))+"lfa.tmp",ExtractFilePath(ParamStr(0))+"lfh.tmp");
  ignore (ExtractFilePath(ParamStr(0))+"laa.tmp",ExtractFilePath(ParamStr(0))+"lah.tmp");
  remove ((ExtractFilePath(ParamStr(0))+"lca.tmp").c_str());
  remove ((ExtractFilePath(ParamStr(0))+"lfa.tmp").c_str());
  remove ((ExtractFilePath(ParamStr(0))+"laa.tmp").c_str());
  HexToFile (ExtractFilePath(ParamStr(0))+"lah.tmp",ExtractFilePath(ParamStr(0))+"la.tmp");
  HexToFile (ExtractFilePath(ParamStr(0))+"lch.tmp",ExtractFilePath(ParamStr(0))+"lc.tmp");
  HexToFile (ExtractFilePath(ParamStr(0))+"lfh.tmp",ExtractFilePath(ParamStr(0))+"lf.tmp");
  remove ((ExtractFilePath(ParamStr(0))+"lch.tmp").c_str());
  remove ((ExtractFilePath(ParamStr(0))+"lfh.tmp").c_str());
  remove ((ExtractFilePath(ParamStr(0))+"lah.tmp").c_str());
  SideBar->CompleteIcon->LoadFromFile(ExtractFilePath(ParamStr(0))+"lc.tmp");
  SideBar->CurrentIcon->LoadFromFile(ExtractFilePath(ParamStr(0))+"la.tmp");
  SideBar->FutureIcon->LoadFromFile(ExtractFilePath(ParamStr(0))+"lf.tmp");
  remove ((ExtractFilePath(ParamStr(0))+"lc.tmp").c_str());
  remove ((ExtractFilePath(ParamStr(0))+"lf.tmp").c_str());
  remove ((ExtractFilePath(ParamStr(0))+"la.tmp").c_str());
  if (!DirectoryExists ("C:\\TEMP"))
    CreateDirectory ("C:\\TEMP\\",NULL);
  mTempDir = GetNewTempDir ();
  CreateDirectory (mTempDir.c_str(),NULL);
  bool iam = false;
  if (ParamStr(1)!=""&&ParamStr(1)!="-u")
  {
    if (!ExtractAll (mTempDir))
    {
      RemoveDirectory (mTempDir.c_str());
      Application->Terminate();
      return;
    }
  }
  else
  {
    if (!SelfExtractAll (mTempDir))
    {
      RemoveDirectory (mTempDir.c_str());
      Application->Terminate();
      return;
    }
    iam = true;
  }
  if (!FileExists (mTempDir+"install.vis"))
  {
    Application->MessageBoxA("ВНИМАНИЕ: Пакет повреждён. Установка невозможна","Ошибка",MB_OK|MB_ICONERROR);
    if (ParamStr(1)=="")
      SelfCleanup (mTempDir);
    else Cleanup (mTempDir);
    Application->Terminate();
    return;
  }
  LoadScript (mTempDir+"install.vis");
  AnsiString A = GetShortDir ();
  TSearchRec sr;
  if (WalkFirst (A,NULL,sr))
    while (WalkNext (A,NULL,sr));
  FindClose (sr);
  TRegistry *Reg = new TRegistry;
  Reg->RootKey=HKEY_CLASSES_ROOT;
  if (Reg->KeyExists ("Vmx Installer\\Installed Apps\\"+RegKey))
  {
    Wit1L->Visible=false;
    ModifyBtn->Visible=true;
    ReinstallBtn->Visible=true;
    RemoveBtn->Visible=true;
    ModifyIL->Visible=true;
    ReinstallIL->Visible=true;
    RemoveIL->Visible=true;
    SActIL->Visible=true;
    if (!Reg->OpenKey("Vmx Installer\\Installed Apps\\"+RegKey,false))
      Close();
    int n = Reg->ReadInteger("InstalledFeaturesCount");
    TStrings *Feats = new TStringList;
    for (int i = 0; i < n; i++)
      Feats->Add(Reg->ReadString("Feature"+IntToStr(i)));
    for (int i = 0; i < SFeats->Count; i++)
      CheckTree (SFeats->Strings[i],Feats->IndexOf(SFeats->Strings[i])>-1);
    delete Feats;
    Reg->CloseKey();
  }
  delete Reg;
  if (ParamStr(1)=="-u"&&iam)
  {
    ModifyBtn->Visible=false;
    ReinstallBtn->Visible=false;
    RemoveBtn->Visible=false;
    ModifyIL->Visible=false;
    ReinstallIL->Visible=false;
    RemoveIL->Visible=false;
    SActIL->Visible=false;
    if (Application->MessageBox("Программа будет удалена с Вашего компьютера. Продолжить?", "Подтверждение", MB_YESNO|MB_ICONQUESTION)==IDYES)
      RemoveApp ();
    SelfCleanup (mTempDir);
    RemoveDirectory (mTempDir.c_str());
    Application->Terminate();
  }
  else if (ParamStr(1)!=""&&ParamStr(1)!="-u"&&ParamStr(2)=="-u")
  {
    ModifyBtn->Visible=false;
    ReinstallBtn->Visible=false;
    RemoveBtn->Visible=false;
    ModifyIL->Visible=false;
    ReinstallIL->Visible=false;
    RemoveIL->Visible=false;
    SActIL->Visible=false;
    if (Application->MessageBox("Программа будет удалена с Вашего компьютера. Продолжить?", "Подтверждение", MB_YESNO|MB_ICONQUESTION)==IDYES)
      RemoveApp ();
    Cleanup (mTempDir);
    RemoveDirectory (mTempDir.c_str());
    Application->Terminate();
  }
}
//---------------------------------------------------------------------------

bool __fastcall TMainForm::WalkFirst (AnsiString Path, TmTreeItem *It, TSearchRec &sr)
{
  if (FindFirst (Path+"*",faDirectory,sr)==0)
  {
    int a = sr.Attr&faDirectory;
    if (a&&sr.Name!="."&&sr.Name!="..")
    {
      TmTreeItem *i;
      if (It==NULL)
        i = ShortcutTree->Add(sr.Name);
      else
        i = It->AddChild(sr.Name);
      if (i != NULL)
      {
        TSearchRec sr2;
        if (WalkFirst (Path+sr.Name+"\\",i,sr2))
          while (WalkNext (Path+sr.Name+"\\",i,sr2));
        FindClose (sr2);
      }
    }
    return true;
  }
  else return false;
}

bool __fastcall TMainForm::WalkNext (AnsiString Path, TmTreeItem *It, TSearchRec &sr)
{
  if (FindNext(sr)==0)
  {
    int a = sr.Attr&faDirectory;
    if (a&&sr.Name!="."&&sr.Name!="..")
    {
      TmTreeItem *i;
      if (It==NULL)
        i = ShortcutTree->Add(sr.Name);
      else
        i = It->AddChild(sr.Name);
      if (i != NULL)
      {
        TSearchRec sr2;
        if (WalkFirst (Path+sr.Name+"\\",i,sr2))
          while (WalkNext (Path+sr.Name+"\\",i,sr2));
        FindClose (sr2);
      }
    }
    return true;
  }
  else return false;
}

AnsiString __fastcall TMainForm::GetShortDir (void)
{
  char *lpBuffer = new char [MAX_PATH];
  LPITEMIDLIST pidlPrograms;
  SHGetSpecialFolderLocation(Handle, CSIDL_PROGRAMS, &pidlPrograms);
  SHGetPathFromIDList(pidlPrograms, lpBuffer);
  AnsiString A = lpBuffer;
  A+="\\";
  return A;
}

void __fastcall TMainForm::FormCloseQuery(TObject *Sender, bool &CanClose)
{
  if (ReallyClose)
  {
    CanClose = true;
    return;
  }
  if (!ReallyClose&&Application->MessageBoxA("Установка не завершена. Прервать?","Подтвердите",MB_YESNO|MB_ICONQUESTION)==IDYES)
    CanClose = true;
  else CanClose = false;
  if (ReallyClose)
    CanClose = true;
}
//---------------------------------------------------------------------------

// код распаковки архивов с помощью extract.dll

typedef void TFeedbackFunc (BYTE);
typedef void TCharFunc (char *);
typedef void __declspec(dllimport) TVoidFunc (void);
typedef void __declspec(dllimport) TStringFunction (char *);
typedef void __declspec(dllimport) TInitFunc (TFeedbackFunc*,TCharFunc*);
typedef void __declspec(dllimport) TCryptFunc (char *, char *, char *);

TStringFunction *pOpen, *pExtract, *pAdd;
TCryptFunc *pDecrypt;
TVoidFunc *pCancel;
TInitFunc *pInit;
void Feed (BYTE Progress)
{
  MainForm->ProgressBar->Progress=Progress;
  Application->ProcessMessages();
}

void FeedFile (char *File)
{
  MainForm->FileL->Caption=ExtractFileName(File);
}

HMODULE hExtract, hDecrypt;

bool __fastcall InitExtractDLL (void)
{
  hExtract = LoadLibrary ((mTempDir+"extract.dll").c_str());
  if (hExtract == NULL)
    return false;
  pInit = (TInitFunc*)GetProcAddress(hExtract,"_InitFeedback");
  if (pInit == NULL)
    return false;
  pInit (&Feed,&FeedFile);
  pCancel = (TVoidFunc*) GetProcAddress(hExtract,"_CancelOps");
  if (pCancel==NULL)
    return false;
  pOpen = (TStringFunction*) GetProcAddress (hExtract, "_OpenArchive");
  if (pOpen==NULL)
    return false;
  pExtract = (TStringFunction*) GetProcAddress (hExtract, "_ExtractArchive");
  if (pExtract==NULL)
    return false;
  pAdd = (TStringFunction*) GetProcAddress (hExtract,"_AddFilesToExtract");
  if (pAdd==NULL)
    return false;
  return true;
}

bool __fastcall InitDecryptDLL (void)
{
  hDecrypt = LoadLibrary ((mTempDir+"encrypt.dll").c_str());
  if (hDecrypt == NULL)
    return false;
  pDecrypt = (TCryptFunc*)GetProcAddress(hDecrypt,"_VMXDecryptFile");
  if (pDecrypt == NULL)
    return false;
  return true;
}

void __fastcall UnloadExtractDLL (void)
{
  FreeLibrary (hExtract);
}

void __fastcall AddExtractStrings (TStrings *S)
{
  for (int i = 0; i < S->Count; i++)
    pAdd(S->Strings[i].c_str());
}

// } код распаковки архивов

AnsiString __fastcall TMainForm::GetProgramFilesDir (void)
{
  char *windir = new char [MAX_PATH];
  GetWindowsDirectory (windir, MAX_PATH);
  AnsiString WinDir = windir;
  for (int i = 0; i < WinDir.Length(); i++)
    if (i == WinDir.Length()-1 || i == WinDir.Length()-2)
      if (windir [i] == '\\')
      {
        windir [i] = '\0';
        break;
      }
  WinDir = windir;
  delete [] windir;
  AnsiString WinDisk;
  if (WinDir.Length()>=3)
    WinDisk = WinDir.SubString(1,3);
  else WinDisk = WinDir + "\\";
  return (WinDisk+"Program Files\\");
}

AnsiString __fastcall TMainForm::GetWinDir (void)
{
  char *windir = new char [MAX_PATH];
  GetWindowsDirectory (windir, MAX_PATH);
  AnsiString WinDir = windir;
  for (int i = 0; i < WinDir.Length(); i++)
    if (i == WinDir.Length()-1 || i == WinDir.Length()-2)
      if (windir [i] == '\\')
      {
        windir [i] = '\0';
        break;
      }
  WinDir = windir;
  return (WinDir);
}

AnsiString __fastcall TMainForm::GetWinSysDir (void)
{
  char *windir = new char [MAX_PATH];
  GetSystemDirectory (windir, MAX_PATH);
  AnsiString WinDir = windir;
  for (int i = 0; i < WinDir.Length(); i++)
    if (i == WinDir.Length()-1 || i == WinDir.Length()-2)
      if (windir [i] == '\\')
      {
        windir [i] = '\0';
        break;
      }
  WinDir = windir;
  return (WinDir);
}

AnsiString __fastcall mSelectDirectory (void)
{
  BROWSEINFO bi;
  LPITEMIDLIST pidlBrowse;
  char* lpBuffer = new char [MAX_PATH];
  bi.hwndOwner = MainForm->Handle;
  bi.pidlRoot = NULL;
  bi.pszDisplayName = lpBuffer;
  bi.lpszTitle = "Выбор директории";
  bi.ulFlags = 0;
  bi.lpfn = NULL;
  bi.lParam = 0;
  pidlBrowse = SHBrowseForFolder(&bi);
  SHGetPathFromIDList(pidlBrowse, lpBuffer);
  return AnsiString(lpBuffer);
}

HRESULT CreateLink(LPCSTR lpszPathObj, LPSTR lpszPathLink, LPSTR lpszDesc)
{
  HRESULT hres;
  IUnknown *pUnk = NULL;
  hres = CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)(&pUnk));
  if (SUCCEEDED(hres))
  {
    IShellLink* psl;
    pUnk->QueryInterface(IID_IShellLink,(void**)(&psl));
    if (SUCCEEDED(hres))
    {
      IPersistFile* ppf;
      psl->SetPath(lpszPathObj);
      psl->SetDescription(lpszDesc);
      hres = psl->QueryInterface(IID_IPersistFile, (void**)(&ppf));
      if (SUCCEEDED(hres))
      {
        wchar_t wsz[MAX_PATH];
        MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1, wsz, MAX_PATH);
        hres = ppf->Save(wsz, TRUE);
        ppf->Release();
      }
      psl->Release();
    }
  }
  return hres;
}

/*+----------REMOVEAPP(void)-----------+*/

void __fastcall TMainForm::RemoveApp (void)
{
  Application->ProcessMessages();
  NextBtn->Enabled=false;
  TStrings *Files = new TStringList;
  TRegistry *Reg = new TRegistry;
  Reg->RootKey=HKEY_LOCAL_MACHINE;
  if (RegKey!="")
    Reg->DeleteKey("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"+RegKey);
  Reg->RootKey=HKEY_CLASSES_ROOT;
  if (!Reg->KeyExists("Vmx Installer\\Installed Apps\\"+RegKey)||RegKey=="")
  {
    BackBtn->Enabled=false;
    NextBtn->Caption="Закрыть";
    ReallyClose = true;
    NextBtn->OnClick=CloseForm;
    delete Reg;
    return;
  }
  Reg->OpenKey("Vmx Installer\\Installed Apps\\"+RegKey,false);
  FILE *fp = fopen (Reg->ReadString("Database").c_str(),"r");
  int n;
  fscanf (fp, "%d\n", &n);
  for (int i = 0; i < n; i++)
    Files->Add(RS(fp));
  fclose (fp);
  remove (Reg->ReadString("Database").c_str());
  ProgressBar->Max=Files->Count;
  AnsiString Dir = ExtractFilePath(Reg->ReadString("Database"));
  if (Dir=="")
  {
    BackBtn->Enabled=false;
    NextBtn->Caption="Закрыть";
    ReallyClose = true;
    NextBtn->OnClick=CloseForm;
    delete Reg;
    return;
  }
  for (int i = 0; i < n; i++)
  {
    if (ExtractFileExt(Archive)!=".vsu")
      remove((Dir+Files->Strings[i]).c_str());
    else remove (FindFile(Dir,Files->Strings[i]).c_str());
    ProgressBar->Progress++;
    Application->ProcessMessages();
  }
  AnsiString LinkDir = Reg->ReadString("ShortcutPath");
  TStrings *Feats = new TStringList;
  n = Reg->ReadInteger("InstalledFeaturesCount");
  for (int i = 0; i < n; i++)
    Feats->Add(Reg->ReadString("Feature"+IntToStr(i)));
  TStrings *Shs = new TStringList;
  for (int i = 0; i < SFeats->Count; i++)
    if (Feats->IndexOf(SFeats->Strings[i])>-1)
      Shs->AddStrings(FeatsShs[i]);
  for (int i = 0; i < Shs -> Count; i++)
    remove ((LinkDir+Shs->Strings[i]+".lnk").c_str());
  delete Shs;
  RemoveDirectory (LinkDir.c_str());
  RemoveDirectory (Dir.c_str());
  Reg->DeleteKey("");
  delete Reg;
  delete Files;
  Application->ProcessMessages();
  Application->MessageBoxA("Удаление программы прошло успешно.","Информация",MB_OK|MB_ICONINFORMATION);
  BackBtn->Enabled=false;
  NextBtn->Caption="Закрыть";
  ReallyClose = true;
  NextBtn->OnClick=CloseForm;
}

void __fastcall TMainForm::CloseForm (TObject *Sender)
{
  ReallyClose = true;
  Close ();
}
void __fastcall TMainForm::LicenseChangeScrollMax(TObject *Sender)
{
  LicScroll->Max=License->ScrollMax+1;
  LicScroll->Pos=License->ScrollPos;        
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::LicScrollChangePos(TObject *Sender)
{
  License->ScrollPos=LicScroll->Pos;
}
//---------------------------------------------------------------------------

/*
СКРИНЫ {
1. Wit1L
2. License; LicScroll; LicCheck; LicIL
3. SetupTypeIL; INormalBtn; IMinBtn; ICustomBtn; INormalL; IMinL1; IMinL2; ICustL1; ICustL2
опять загружаю инфу о запароленности
если запаролено:
4. PasswordEdit; PasswordIL; MatrixEdit; MatrixIL
ПРОВЕРКА пароля:
        int a = 0;
        int b = 5;
        int c;
        try
        {
          c = b/a;
        }
        catch (EDivByZero)
        {
          <ПРОВЕРКА пароля>
        }
        Application->Terminate();
ЕСЛИ выбрана выборочная установка:
5. FeatureIL; FeatureTree; FeatureScroll
6. SelDirIL; SelDirEdit; SelDirBtn
7. ShortcutTree; ShortScroll; ShortIL; SelSDEdit
8. Wit2L
-> УСТАНОВКА
}
*/
#define SHOWHI Wit1L->Visible=true;CurScr=isHi
#define HIDEHI Wit1L->Visible=false
#define SHOWLIC License->Visible=true;LicScroll->Visible=true;LicCheck->Visible=true;LicIL->Visible=true;CurScr=isLicense
#define HIDELIC License->Visible=false;LicScroll->Visible=false;LicCheck->Visible=false;LicIL->Visible=false
#define SHOWSETUPTYPE SetupTypeIL->Visible=true; INormalBtn->Visible=true; IMinBtn->Visible=true; ICustomBtn->Visible=true; INormalL->Visible=true; IMinL1->Visible=true; IMinL2->Visible=true; ICustL1->Visible=true; ICustL2->Visible=true;CurScr=isSelectType
#define HIDESETUPTYPE SetupTypeIL->Visible=false; INormalBtn->Visible=false; IMinBtn->Visible=false; ICustomBtn->Visible=false; INormalL->Visible=false; IMinL1->Visible=false; IMinL2->Visible=false; ICustL1->Visible=false; ICustL2->Visible=false
#define SHOWREADY Wit2L->Visible=true;CurScr=isNext
#define HIDEREADY Wit2L->Visible=false
#define SHOWFEATS FeatureIL->Visible=true; FeatureTree->Visible=true; FeatureScroll->Visible=true;CurScr=isSelFeat
#define HIDEFEATS FeatureIL->Visible=false; FeatureTree->Visible=false; FeatureScroll->Visible=false
#define SHOWPASS PasswordEdit->Visible=true; PasswordIL->Visible=true;MatrixIL->Visible=true;MatrixEdit->Visible=true;CurScr=isPassword
#define HIDEPASS PasswordEdit->Visible=false; PasswordIL->Visible=false;MatrixIL->Visible=false;MatrixEdit->Visible=false
#define SHOWSELDIR SelDirIL->Visible=true; SelDirEdit->Visible=true; SelDirBtn->Visible=true;CurScr=isSelDir
#define HIDESELDIR SelDirIL->Visible=false; SelDirEdit->Visible=false; SelDirBtn->Visible=false
#define SHOWSHORTDIR ShortcutTree->Visible=true; ShortScroll->Visible=true; ShortIL->Visible=true; SelSDEdit->Visible=true;CurScr=isSelShortDir
#define HIDESHORTDIR ShortcutTree->Visible=false; ShortScroll->Visible=false; ShortIL->Visible=false; SelSDEdit->Visible=false
#define SHOWPROGRESS CopyInfoL->Visible=true;FileL->Visible=true;ProgressBar->Visible=true
#define HIDEPROGRESS CopyInfoL->Visible=false;FileL->Visible=false;ProgressBar->Visible=false

void __fastcall TMainForm::INormalBtnClick(TObject *Sender)
{
  INormalBtn->Down=false;
  IMinBtn->Down=false;
  ICustomBtn->Down=false;
  ((TVmxXPBitBtn*)Sender)->Down=true;
}
//---------------------------------------------------------------------------

AnsiString __fastcall DiskSpaceToStr (__int64 s)
{
  if (s < 1024)
    return IntToStr((__int64)s)+" байт";
  else if (s >= 1024 && s < 1024*1024)
    return IntToStr(s/1024) + " Кб";
  else if (s >= 1024*1024 && s < 1024*1024*1024)
    return IntToStr(s/(1024*1024)) + " Мб";
  else return IntToStr(s/(1024*1024*1024)) + "Гб";
}

void __fastcall TMainForm::DiskSpaceString (void)
{
  ULARGE_INTEGER Ava, Bts, FBts;
  ::GetDiskFreeSpaceEx (SelDirEdit->Text.c_str(),&Ava,&Bts,&FBts);
  __int64 SREQ = 0;
  __int64 SAVA = Ava.QuadPart;
  TStrings *Feats = new TStringList;
  switch (sit)
  {
    case itNormal:
      Feats->Assign(NFeats);
      break;
    case itMinimal:
      Feats->Assign(MFeats);
      break;
    case itCustom:
      for (int i = 0; i < SFeats->Count; i++)
      {
        if (FeatureChecked (SFeats->Strings[i])||RFeats->IndexOf(SFeats->Strings[i])>-1)
          Feats->Add(SFeats->Strings[i]);
      }
      break;
  }
  for (int i = 0; i < SFeats->Count; i++)
  {
    if (Feats->IndexOf(SFeats->Strings[i])>-1)
      SREQ+=FeatsSizes [i];
  }
  if (SREQ>SAVA)
    NextBtn->Enabled=false;
  Wit2L->Caption=fixk+"\n\rНеобходимо места на диске: "+DiskSpaceToStr(SREQ)+"\n\rДоступно места: "+DiskSpaceToStr(SAVA);
  delete Feats;
}

void __fastcall TMainForm::NextBtnClick(TObject *Sender)
{
  if (RemoveBtn->Visible)
  {
    if (ReinstallBtn->Down)
      Wit1L->Visible=true;
    else if (RemoveBtn->Down)
    {
      if (Application->MessageBox("Программа будет удалена с Вашего компьютера. Продолжить?", "Подтверждение", MB_YESNO|MB_ICONQUESTION)==IDYES)
      {
        RemoveApp ();
        ReallyClose = true;
        Close ();
        return;
      }
      else return;
    }
    else
    {
      modMode = true;
      TRegistry *Reg = new TRegistry;
      Reg->RootKey=HKEY_CLASSES_ROOT;
      Reg->OpenKey("Vmx Installer\\Installed Apps\\"+RegKey,false);
      int N = Reg->ReadInteger("InstalledFeaturesCount");
      TStrings *Feats = new TStringList;
      for (int i = 0; i < N; i++)
        Feats->Add(Reg->ReadString("Feature"+IntToStr(i)));
      for (int i = 0; i < SFeats->Count; i++)
        CheckTree(SFeats->Strings[i],Feats->IndexOf(SFeats->Strings[i])>-1);
      delete Reg;
      delete Feats;
      SHOWFEATS;
    }
    ModifyBtn->Visible=false;
    ReinstallBtn->Visible=false;
    RemoveBtn->Visible=false;
    ModifyIL->Visible=false;
    ReinstallIL->Visible=false;
    RemoveIL->Visible=false;
    SActIL->Visible=false;
    return;
  }
  BackBtn->Enabled=true;
  int a = 0, b = 5, c;
  switch (CurScr)
  {
    case isHi:
      HIDEHI;
      if(ShowLic)
      {
        SHOWLIC;
        SideBar->Current=1;
      }
      else
      {
        int a = 0, b = 5, c;
        try
        {
          c = b/a;
        }
        catch (EDivByZero &a)
        {
          if (GetPassworded())
          {
            SHOWPASS;
          }
          else
          {
            SHOWSETUPTYPE;
            SideBar->Current=2;
          }
          return;
        }
        TCloseAction A;
        FormClose (NULL, A);
        Application->Terminate();
      }
      break;
    case isLicense:
      HIDELIC;
      if (!LicCheck->Checked)
        goto XXXXXX;
      try
      {
        c = b/a;
      }
      catch (EDivByZero &a)
      {
        if (GetPassworded())
        {
          SHOWPASS;
        }
        else
        {
          SHOWSETUPTYPE;
          SideBar->Current=2;
        }
        return;
      }
      XXXXXX:
      TCloseAction A;
      FormClose (NULL, A);
      Application->Terminate();
      break;
    case isSelectType:
      HIDESETUPTYPE;
      if (INormalBtn->Down)
        sit = itNormal;
      else if (IMinBtn->Down)
        sit = itMinimal;
      else sit = itCustom;
      if (sit == itCustom)
      {
        SHOWFEATS;
      }
      else
      {
        SHOWREADY;
        DiskSpaceString();
      }
      SideBar->Current=3;
      break;
    case isPassword:
      if (MatrixEdit->Text.Length()!=48)
      {
        Application->MessageBoxA("Введите верный 48-значный ключ","Ошибка",MB_OK|MB_ICONERROR);
        return;
      }
      try
      {
        c = b/a;
      }
      catch (EDivByZero &e)
      {
        VerifyPassword ();
        key = PasswordEdit->Text+MatrixEdit->Text;
        PasswordEdit->Text="";
        HIDEPASS;
        SHOWSETUPTYPE;
        SideBar->Current=2;
        return;
      }
      TCloseAction a;
      FormClose (NULL, a);
      Application->Terminate();
      break;
    case isSelFeat:
      HIDEFEATS;
      if (!modMode)
      {
        SHOWSELDIR;
      }
      else
      {
        SHOWPROGRESS;
        AddOrRemove ();
        HIDEPROGRESS;
        FinishL->Visible=true;
        CurScr = isFinished;
      }
      break;
    case isSelDir:
      HIDESELDIR;
      SHOWSHORTDIR;
      break;
    case isSelShortDir:
      HIDESHORTDIR;
      SHOWREADY;
      DiskSpaceString();
      break;
    case isNext:
      HIDEREADY;
      SHOWPROGRESS;
      Install ();
      ReallyClose = true;
      HIDEPROGRESS;
      FinishL->Visible=true;
      NextBtn->Caption="Завершить >";
      BackBtn->Enabled=false;
      ReallyClose = true;
      CurScr=isFinished;
      break;
    case isFinished:
      FinishL->Visible=false;
      ReallyClose = true;
      Close ();
      break;
  }
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action)
{
  if (ParamStr(1)!="")
    Cleanup(mTempDir);
  else SelfCleanup(mTempDir);
  RemoveDirectory (mTempDir.c_str());
}
//---------------------------------------------------------------------------

bool __fastcall TMainForm::GetPassworded (void)
{
  if (!FileExists (mTempDir+"password.enc"))
  {
    TCloseAction Action;
    FormClose (NULL, Action);
    Visible=false;
    Application->Terminate();
  }
  else
  {
    if (!FileExists (mTempDir+"password.dec") || !FileExists (mTempDir+"password.mtx"))
      return true;
    else
    {
      FILE *fp = fopen ((mTempDir+"password.dec").c_str(),"r");
      AnsiString ComStr = RS (fp);
      fclose (fp);
      int a = 5, b = 0, c;
      try
      {
        c = a/b;
      }
      catch (EDivByZero &Err)
      {
        AnsiString DecStr = DecodeFileIntoString (mTempDir+"password.enc",mTempDir+"password.mtx");
        if (DecStr != ComStr)
          return true;
        else return false;
      }
      return true;
    }
  }
}

void __fastcall TMainForm::VerifyPassword (void)
{
  if (!FileExists (mTempDir+"password.enc"))
  {
    TCloseAction Action;
    FormClose (NULL, Action);
    Visible=false;
    Application->Terminate();
  }
  else
  {
    TFileStream *fs = new TFileStream (mTempDir+"matrix.pss",fmOpenWrite|fmCreate);
    AnsiString H;
    BYTE b;
    for (int i = 0; i < 24; i++)
    {
      H="";
      H+=MatrixEdit->Text[i*2+1];
      H+=MatrixEdit->Text[i*2+2];
      b = StrToInt ("0x"+H);
      fs->Write(&b,1);
    }
    delete fs;
    int A = 0, B = 5, C;
    try
    {
      C = B/A;
    }
    catch (EDivByZero &e)
    {
      AnsiString DecText = DecodeFileIntoString (mTempDir+"password.enc",mTempDir+"matrix.pss");
      if (DecText != PasswordEdit->Text)
      {
        AnsiString A = "Пароль неверен. Установка сейчас будет завершена";
        #ifdef __DEBUG__
        A+="; "+DecText;
        #endif
        Application->MessageBox(A.c_str(), "Неверный пароль", MB_OK|MB_ICONERROR);
        TCloseAction Action;
        FormClose (NULL, Action);
        Visible=false;
        Application->Terminate();
      }
    }
    remove ((mTempDir+"matrix.pss").c_str());
  }
}

void __fastcall TMainForm::BackBtnClick(TObject *Sender)
{
  NextBtn->Enabled=true;
  switch (CurScr)
  {
    case isLicense:
      HIDELIC;
      SHOWHI;
      BackBtn->Enabled=false;
      SideBar->Current=0;
      break;
    case isSelectType:
      HIDESETUPTYPE;
      if (GetPassworded())
      {
        SHOWPASS;
        SideBar->Current=0;
      }
      else
      {
        if (ShowLic)
        {
          SHOWLIC;
          SideBar->Current=1;
        }
        else
        {
          SHOWHI;
          SideBar->Current=0;
          BackBtn->Enabled=false;
        }
      }
      break;
    case isPassword:
      HIDEPASS;
      if (ShowLic)
      {
        SHOWLIC;
        SideBar->Current=1;
      }
      else
      {
        SHOWHI;
        SideBar->Current=0;
      }
      break;
    case isSelFeat:
      HIDEFEATS;
      SHOWSETUPTYPE;
      break;
    case isSelDir:
      HIDESELDIR;
      SHOWFEATS;
      break;
    case isSelShortDir:
      HIDESHORTDIR;
      SHOWSELDIR;
      break;
    case isNext:
      HIDEREADY;
      if (sit == itCustom)
      {
        SHOWSHORTDIR;
      }
      else
      {
        SHOWSETUPTYPE;
      }
      break;
  }
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FormCreate(TObject *Sender)
{
  SFeats = new TStringList;
  NFeats = new TStringList;
  MFeats = new TStringList;
  DFeats = new TStringList;
  RFeats = new TStringList;
  LTWHControls [0] = this;
  LTWHControls [1] = CaptionL;
  LTWHControls [2] = DragCaption;
  LTWHControls [3] = CloseBtn;
  LTWHControls [4] = MinimizeBtn;
  LTWHControls [5] = Wit1L;
  LTWHControls [6] = SideBar;
  LTWHControls [7] = ProgressBar;
  LTWHControls [8] = CopyInfoL;
  LTWHControls [9] = License;
  LTWHControls [10] = LicCheck;
  LTWHControls [11] = LicIL;
  LTWHControls [12] = LicScroll;
  LTWHControls [13] = SetupTypeIL;
  LTWHControls [14] = INormalL;
  LTWHControls [15] = IMinL1;
  LTWHControls [16] = IMinL2;
  LTWHControls [17] = ICustL1;
  LTWHControls [18] = ICustL2;
  LTWHControls [19] = PasswordIL;
  LTWHControls [20] = FeatureTree;
  LTWHControls [21] = FeatureScroll;
  LTWHControls [22] = FeatureIL;
  LTWHControls [23] = SelDirIL;
  LTWHControls [24] = ShortcutTree;
  LTWHControls [25] = ShortScroll;
  LTWHControls [26] = ShortIL;
  LTWHControls [27] = Wit2L;
  LTWHControls [28] = FinishL;
  LTWHControls [29] = MatrixIL;
  LTWHControls [30] = BackBtn;
  LTWHControls [31] = NextBtn;
  LTWHControls [32] = ICustomBtn;
  LTWHControls [33] = IMinBtn;
  LTWHControls [34] = INormalBtn;
  LTWHControls [35] = SelDirBtn;
  LTWHControls [36] = ModifyBtn;
  LTWHControls [37] = ModifyIL;
  LTWHControls [38] = ReinstallBtn;
  LTWHControls [39] = ReinstallIL;
  LTWHControls [40] = RemoveBtn;
  LTWHControls [41] = RemoveIL;
  LTWHControls [42] = SActIL;
  LTWHControls [43] = PasswordEdit;
  LTWHControls [44] = SelDirEdit;
  LTWHControls [45] = SelSDEdit;
  LTWHControls [46] = MatrixEdit;
  ltwhcn = 47;
  XPBitBtns [0] = ModifyBtn;
  XPBitBtns [1] = ReinstallBtn;
  XPBitBtns [2] = RemoveBtn;
  XPBitBtns [3] = INormalBtn;
  XPBitBtns [4] = IMinBtn;
  XPBitBtns [5] = ICustomBtn;
  XPBitBtns [6] = BackBtn;
  XPBitBtns [7] = NextBtn;
  XPBitBtns [8] = SelDirBtn;
  xbbn = 9;
  LoadCaptions [0] = CaptionL;
  LoadCaptions [1] = Wit1L;
  LoadCaptions [2] = CopyInfoL;
  LoadCaptions [3] = LicIL;
  LoadCaptions [4] = SetupTypeIL;
  LoadCaptions [5] = INormalL;
  LoadCaptions [6] = IMinL1;
  LoadCaptions [7] = IMinL2;
  LoadCaptions [8] = ICustL1;
  LoadCaptions [9] = ICustL2;
  LoadCaptions [10] = PasswordIL;
  LoadCaptions [11] = FeatureIL;
  LoadCaptions [12] = SelDirIL;
  LoadCaptions [13] = ShortIL;
  LoadCaptions [14] = Wit2L;
  LoadCaptions [15] = FinishL;
  LoadCaptions [16] = MatrixIL;
  LoadCaptions [17] = ModifyIL;
  LoadCaptions [18] = ReinstallIL;
  LoadCaptions [19] = RemoveIL;
  LoadCaptions [20] = SActIL;
  lcn = 21;
}
//---------------------------------------------------------------------------

bool __fastcall CheckItem (TmTreeItem *Item, AnsiString Name, bool C)
{
  for (int i = 0; i < Item->NChild; i++)
  {
    if (Item->Childs[i]->Text==Name)
    {
      Item->Childs[i]->Checked=C;
      return true;
    }
    else
    {
      if (CheckItem (Item->Childs[i],Name,C))
        return true;
    }
  }
  return false;
}

void __fastcall TMainForm::CheckTree (AnsiString Name, bool C)
{
  for (int i = 0; i < FeatureTree->ICount; i++)
  {
    if (FeatureTree->Items[i]->Text==Name)
      FeatureTree->Items[i]->Checked=C;
    else
    {
      if (CheckItem (FeatureTree->Items[i],Name,C))
        return;
    }
  }
}

void __fastcall TMainForm::LoadScript (AnsiString File)
{
  AnsiString SD = ExtractFilePath (File); // Source Directory
  FILE *fp = fopen (File.c_str(),"r");
  FeatureTree->LoadFromFILE(fp);
  int n, n2;
  fscanf (fp, "%d\n", &n);
  FeatsSizes = new __int64 [n];
  for (int i = 0; i < n; i++)
  {
    SFeats->Add(RS(fp));
    fscanf (fp, "%d\n", &n2);
    FeatsFiles[i] = new TStringList;
    for (int j = 0; j < n2; j++)
      FeatsFiles[i]->Add(RS(fp));
    FeatsSizes[i] = StrToInt(RS(fp));
    fscanf (fp, "%d\n", &n2);
    FeatsShs[i] = new TStringList;
    FeatsSms[i] = new TStringList;
    FeatsSds[i] = new TStringList;
    for (int j = 0; j < n2; j++)
    {
      FeatsShs[i]->Add(RS(fp));
      FeatsSms[i]->Add(RS(fp));
      FeatsSds[i]->Add(RS(fp));
    }
  }
  fscanf (fp, "%d\n", &n);
  for (int i = 0; i < n; i++)
    NFeats->Add(RS(fp));
  fscanf (fp, "%d\n", &n);
  ICustomBtn->Enabled=(n==1?true:false);
  ICustL1->Enabled=(n==1?true:false);
  ICustL2->Enabled=(n==1?true:false);
  if (n==1)
  {
    fscanf (fp, "%d\n", &n);
    for (int i = 0; i < n; i++)
      RFeats->Add(RS(fp));
    fscanf (fp, "%d\n", &n);
    for (int i = 0; i < n; i++)
      DFeats->Add(RS(fp));
    for (int i = 0; i < SFeats->Count; i++)
      CheckTree (SFeats->Strings[i],RFeats->IndexOf(SFeats->Strings[i])>-1);
  }
  fscanf (fp, "%d\n", &n);
  IMinBtn->Enabled=(n==1?true:false);
  IMinL1->Enabled=(n==1?true:false);
  IMinL2->Enabled=(n==1?true:false);
  if (n == 1)
  {
    fscanf (fp, "%d\n", &n);
    for (int i = 0; i < n; i++)
      MFeats->Add(RS(fp));
  }
  fscanf (fp, "%d\n", &n);
  if (n==1)
  {
    AnsiString A = RS(fp);
    CreateDirectory ((mTempDir+"Skin\\").c_str(),NULL);
    DecompileIntoFolder (mTempDir+A,mTempDir+"Skin\\");
    A = ChangeFileExt (A,".vts");
    LoadSkin(mTempDir+"Skin\\"+A);
    TSearchRec sr;
    if (FindFirst (mTempDir+"Skin\\*",faAnyFile,sr)==0)
    {
      remove ((mTempDir+"Skin\\"+sr.Name).c_str());
      while (FindNext (sr)==0)
        remove ((mTempDir+"Skin\\"+sr.Name).c_str());
    }
    FindClose (sr);
    RemoveDirectory ((mTempDir+"Skin\\").c_str());
  }
  AnsiString DD = RS(fp);
  if (DD[1]=='%')
  {
    AnsiString Var;
    switch (DD[2])
    {
      case 'W': Var = GetWinDir (); break;
      case 'P': Var = GetProgramFilesDir (); break;
      case 'S': Var = GetWinSysDir (); break;
    }
    SelDirEdit->Text=Var+DD.SubString(4,DD.Length()-1);
  }
  else
    SelDirEdit->Text=DD;
  Archive = RS(fp);
  RegKey = RS(fp);
  UninstallName = RS(fp);
  SelSDEdit->Text = RS(fp);
  fscanf (fp, "%d\n", &n);
  if (n==1)
  {
    fscanf (fp, "%d\n", &n);
    for (int i = 0; i < n; i++)
      License->Lines->Add(RS(fp));
    ShowLic=true;  
  }
  fclose (fp);
  fixk = Wit2L->Caption;
}

void __fastcall TMainForm::SelDirBtnClick(TObject *Sender)
{
  AnsiString Dir = mSelectDirectory ();
  if (Dir != "")
    SelDirEdit->Text=Dir;        
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::ShortcutTreeClickItem(TObject *Sender,
      TmTreeItem *Item)
{
  AnsiString Path = Item->Text;
  TmTreeItem *It = Item->Parent;
  while (It != NULL)
  {
    Path = It->Text+"\\"+Path;
    It = It->Parent;
  }
  SelSDEdit->Text=Path;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::ShortScrollChangePos(TObject *Sender)
{
  ShortcutTree->ScrollPos=ShortScroll->Pos;        
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::ShortcutTreeChangeScrollMax(TObject *Sender)
{
  ShortScroll->Max=ShortcutTree->ScrollMax+2;        
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FeatureTreeChangeScrollMax(TObject *Sender)
{
  FeatureScroll->Max=FeatureTree->ScrollMax+2;        
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FeatureScrollChangePos(TObject *Sender)
{
  FeatureTree->ScrollPos=FeatureScroll->Pos;
}
//---------------------------------------------------------------------------

bool __fastcall WalkItem (TmTreeItem *Item, AnsiString Name)
{
  for (int i = 0; i < Item->NChild; i++)
  {
    if (Item->Childs[i]->Text==Name)
      return Item->Childs[i]->Checked;
    else
    {
      bool a = WalkItem (Item->Childs[i],Name);
      if (a) return true;
    }
  }
  return false;
}

bool __fastcall TMainForm::FeatureChecked (AnsiString Name)
{
  for (int i = 0; i < FeatureTree->ICount; i++)
  {
    if (FeatureTree->Items[i]->Text==Name)
      return FeatureTree->Items[i]->Checked;
    else
    {
      bool a = WalkItem (FeatureTree->Items[i],Name);
      if (a) return true;
    }
  }
  return false;
}

void __fastcall PROC2 (int a)
{
  MainForm->ProgressBar->Progress=a;
}

void __fastcall TMainForm::Install (void)
{
  bool vsu_ext = false;
  int a=5, b=0, c;
  try
  {
    c=a/b;
  }
  catch (EDivByZero &EE)
  {
    if (GetPassworded())
    {
      if (!InitDecryptDLL())
      {
        Application->MessageBox("Файл encrypt.dll не найден или повреждён. Установка невозможна", "Ошибка", MB_OK|MB_ICONERROR);
        return;
      }
      rename ((mTempDir+Archive).c_str(),(mTempDir+Archive+".tmp").c_str());
      pDecrypt (key.c_str(),(mTempDir+Archive+".tmp").c_str(),(mTempDir+Archive).c_str());
      key = "";
      remove ((mTempDir+Archive+".tmp").c_str());
      FreeLibrary(hDecrypt);
    }
    goto XXX;
  }
  return;
XXX:  
  if (!InitExtractDLL())
  {
    if (ExtractFileExt (Archive)!=".vsu")
    {
      Application->MessageBoxA("Файл extract.dll не найден или повреждён. Установка невозможна", "Ошибка", MB_OK|MB_ICONERROR);
      return;
    }
    else vsu_ext = true;
  }
  NextBtn->Caption="Отмена";
  NextBtn->OnClick=CancelInstall;
  AnsiString Dir = SelDirEdit->Text;
  if (Dir[Dir.Length()]!='\\')
    Dir+='\\';
  AnsiString ShDir = GetShortDir ()+SelSDEdit->Text;
  if (ShDir[ShDir.Length()]!='\\')
    ShDir+='\\';
  TStrings *Files = new TStringList;
  TStrings *Feats = new TStringList;
  TStrings *Shs = new TStringList;
  TStrings *Sms = new TStringList;
  TStrings *Sds = new TStringList;
  switch (sit)
  {
    case itNormal:
      Feats->Assign(NFeats);
      break;
    case itMinimal:
      Feats->Assign(MFeats);
      break;
    case itCustom:
      for (int i = 0; i < SFeats->Count; i++)
      {
        if (FeatureChecked (SFeats->Strings[i])||RFeats->IndexOf(SFeats->Strings[i])>-1)
          Feats->Add(SFeats->Strings[i]);
      }
      break;
  }
  for (int i = 0; i < SFeats->Count; i++)
  {
    if (Feats->IndexOf(SFeats->Strings[i])>-1)
    {
      Files->AddStrings (FeatsFiles[i]);
      Shs->AddStrings(FeatsShs[i]);
      Sds->AddStrings(FeatsSds[i]);
      Sms->AddStrings(FeatsSms[i]);
    }
  }
  SideBar->Current=4;
  if (!vsu_ext)
  {
    pOpen ((mTempDir+Archive).c_str());
    AddExtractStrings (Files);
    CreateDirectory (Dir.c_str(),NULL);
    pExtract (Dir.c_str());
    while (ProgressBar->Progress!=100)
      Application->ProcessMessages();
    UnloadExtractDLL ();
  }
  else
    VSUExtractFiles (mTempDir+Archive,Files,Dir,NULL,PROC2);
  FILE *fp = fopen ((Dir+"install.dat").c_str(),"w");
  fprintf (fp, "%d\n", Files->Count);
  for (int i = 0; i < Files->Count; i++)
    fprintf (fp, "%s\n", Files->Strings[i].c_str());
  fclose (fp);
  // теперь ярлыки
  SideBar->Current=5;
  if (Shs->Count>0)
  {
    CreateDirectory (ShDir.c_str(),NULL);
    for (int i = 0; i < Sms->Count; i++)
    {
      AnsiString A = Sms->Strings[i];
      if (A[1]=='%')
      {
        switch (A[2])
        {
          // Installdir
          case 'I': A = Dir+A.SubString(4,A.Length()-3);
                    break;
          case 'W': A = GetWinDir()+A.SubString(4,A.Length()-3);
                    break;
          case 'S': A = GetWinSysDir()+A.SubString(4,A.Length()-3);
                    break;
          case 'P': A = GetProgramFilesDir()+A.SubString(4,A.Length()-3);
                    break;
        }
      }
      Sms->Strings[i]=A;
    }
    CoInitialize (NULL);
    for (int i = 0; i < Shs->Count; i++)
      CreateLink (Sms->Strings[i].c_str(),(ShDir+Shs->Strings[i]+".lnk").c_str(),Sds->Strings[i].c_str());
    CoUninitialize ();
  }
  TRegistry *Reg = new TRegistry;
  Reg->RootKey=HKEY_CLASSES_ROOT;
  Reg->OpenKey("Vmx Installer\\Installed Apps\\"+RegKey,true);
  Reg->WriteString ("Database",Dir+"install.dat");
  Reg->WriteInteger ("InstalledFeaturesCount",Feats->Count);
  for (int i = 0; i < Feats->Count; i++)
    Reg->WriteString ("Feature"+IntToStr(i),Feats->Strings[i]);
  Reg->WriteString("ShortcutPath",ShDir);
  Reg->CloseKey ();
  Reg->RootKey=HKEY_LOCAL_MACHINE;
  Reg->OpenKey("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"+RegKey,true);
  Reg->WriteString("DisplayName",UninstallName);
  Reg->WriteString("UninstallString",ParamStr(0)+" "+ParamStr(1)+" -u");
  Reg->CloseKey();
  delete Reg;
  delete Files;
  delete Feats;
  delete Shs;
  delete Sds;
  delete Sms;
  NextBtn->OnClick=NextBtnClick;
  SideBar->Current=6;
  ReallyClose = true;
}

void __fastcall TMainForm::CancelInstall (TObject *Sender)
{
  pCancel ();
  Close ();
}
void __fastcall TMainForm::RemoveBtnClick(TObject *Sender)
{
  ModifyBtn->Down=false;
  ReinstallBtn->Down=false;
  RemoveBtn->Down=false;
  ((TVmxXPBitBtn*)Sender)->Down=true;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::AddOrRemove (void)
{
  bool vsu_ext = false;
  if (!InitExtractDLL())
  {
    if (ExtractFileExt (Archive)!=".vsu")
    {
      Application->MessageBoxA("Файл extract.dll не найден или повреждён. Установка невозможна", "Ошибка", MB_OK|MB_ICONERROR);
      return;
    }
    else vsu_ext = true;
  }
  TRegistry *Reg = new TRegistry;
  Reg->RootKey=HKEY_CLASSES_ROOT;
  Reg->OpenKey ("Vmx Installer\\Installed Apps\\"+RegKey,false);
  AnsiString Dir = ExtractFilePath(Reg->ReadString("Database"));
  AnsiString ShDir = Reg->ReadString("ShortcutPath");
  int N = Reg->ReadInteger("InstalledFeaturesCount");
  TStrings *Feats = new TStringList;
  for (int i = 0; i < N; i++)
    Feats->Add(Reg->ReadString("Feature"+IntToStr(i)));
  TStrings *NFeats = new TStringList;
  TStrings *AFiles = new TStringList;
  TStrings *RFiles = new TStringList;
  TStrings *RShs = new TStringList;
  TStrings *AShs = new TStringList;
  TStrings *ASms = new TStringList;
  TStrings *ASds = new TStringList;
  for (int i = 0; i < SFeats->Count; i++)
  {
    if (FeatureChecked (SFeats->Strings[i]))
      NFeats->Add(SFeats->Strings[i]);
    if (FeatureChecked (SFeats->Strings[i])&&Feats->IndexOf(SFeats->Strings[i])==-1)
    {
      AFiles->AddStrings(FeatsFiles[i]);
      AShs->AddStrings(FeatsShs[i]);
      ASms->AddStrings(FeatsSms[i]);
      ASds->AddStrings(FeatsSds[i]);
    }
    else if (!FeatureChecked (SFeats->Strings[i])&&Feats->IndexOf(SFeats->Strings[i])!=-1)
    {
      RFiles->AddStrings(FeatsFiles[i]);
      RShs->AddStrings(FeatsShs[i]);
    }
  }
  // удаляем...
  for (int i = 0; i < RFiles->Count; i++)
  {
    if (ExtractFileExt (Archive)==".vsu")
      remove (FindFile(Dir,RFiles->Strings[i]).c_str());
    else remove ((Dir+RFiles->Strings[i]).c_str());
  }
  for (int i = 0; i < RShs->Count; i++)
    remove ((ShDir+RShs->Strings[i]+".lnk").c_str());
  // теперь новые
  if (AFiles->Count!=0)
  {
    if (!vsu_ext)
    {
      pOpen ((mTempDir+Archive).c_str());
      AddExtractStrings (AFiles);
      CreateDirectory (Dir.c_str(),NULL);
      pExtract (Dir.c_str());
      while (ProgressBar->Progress!=100)
        Application->ProcessMessages();
      UnloadExtractDLL ();
    }
    else
      VSUExtractFiles (mTempDir+Archive,AFiles,Dir,NULL,PROC2);
  }
  if (AShs->Count>0)
  {
    CreateDirectory (ShDir.c_str(),NULL);
    for (int i = 0; i < ASms->Count; i++)
    {
      AnsiString A = ASms->Strings[i];
      if (A[1]=='%')
      {
        switch (A[2])
        {
          // Installdir
          case 'I': A = Dir+A.SubString(4,A.Length()-4);
                    break;
          case 'W': A = GetWinDir()+A.SubString(4,A.Length()-4);
                    break;
          case 'S': A = GetWinSysDir()+A.SubString(4,A.Length()-4);
                    break;
          case 'P': A = GetProgramFilesDir()+A.SubString(4,A.Length()-4);
                    break;
        }
      }
      ASms->Strings[i]=A;
    }
    CoInitialize (NULL);
    for (int i = 0; i < AShs->Count; i++)
      CreateLink (ASms->Strings[i].c_str(),(ShDir+AShs->Strings[i]+".lnk").c_str(),ASds->Strings[i].c_str());
    CoUninitialize ();
  }
  N = Reg->ReadInteger("InstalledFeaturesCount");
  for (int i = 0; i < N; i++)
    Reg->DeleteValue("Feature"+IntToStr(i));
  Reg->WriteInteger("InstalledFeaturesCount",NFeats->Count);
  for (int i = 0; i < NFeats->Count; i++)
    Reg->WriteString("Feature"+IntToStr(i),NFeats->Strings[i]);
  TStrings *NFiles = new TStringList;
  for (int i = 0; i < SFeats->Count; i++)
    if (NFeats->IndexOf(SFeats->Strings[i])>-1)
      NFiles->AddStrings(FeatsFiles[i]);
  FILE *fp = fopen ((Dir+"install.dat").c_str(),"w");
  fprintf (fp, "%d\n", NFiles->Count);
  for (int i = 0; i < NFiles->Count; i++)
    fprintf (fp, "%s\n", NFiles->Strings[i].c_str());
  fclose (fp);
  delete RShs;
  delete AShs;
  delete ASms;
  delete ASds;
  delete AFiles;
  delete NFiles;
  delete RFiles;
  delete NFeats;
  delete Feats;
  delete Reg;
}

/****************************************/
/* VMX Skinning system 1.0              */
/* Типы:                                */
/* int [i] bool [b] strings [n]         */
/* str [s] color [c]                    */
/* loadimg [l] fstyle [f]               */
/****************************************/

void __fastcall ReadFont (TFont *F, FILE *fp)
{
  F->Color=StrToInt(RS(fp));
  F->Size=StrToInt(RS(fp));
  F->Name=RS(fp);
  AnsiString A = RS(fp);
  bool b=false,i=false,u=false,s=false;
  if (A.Length()>0)
  {
    switch (A[1])
    {
      case 'B':
      case 'b': b = true; break;
      case 'I':
      case 'i': i = true; break;
      case 'U':
      case 'u': u = true; break;
      case 'S':
      case 's': s = true; break;
    }
  }
  if (A.Length()>1)
  {
    switch (A[2])
    {
      case 'B':
      case 'b': b = true; break;
      case 'I':
      case 'i': i = true; break;
      case 'U':
      case 'u': u = true; break;
      case 'S':
      case 's': s = true; break;
    }
  }
  if (A.Length()>2)
  {
    switch (A[3])
    {
      case 'B':
      case 'b': b = true; break;
      case 'I':
      case 'i': i = true; break;
      case 'U':
      case 'u': u = true; break;
      case 'S':
      case 's': s = true; break;
    }
  }
  if (A.Length()>3)
  {
    switch (A[4])
    {
      case 'B':
      case 'b': b = true; break;
      case 'I':
      case 'i': i = true; break;
      case 'U':
      case 'u': u = true; break;
      case 'S':
      case 's': s = true; break;
    }
  }
  F->Style=TFontStyles();
  if (b) F->Style=F->Style<<fsBold;
  if (i) F->Style=F->Style<<fsItalic;
  if (u) F->Style=F->Style<<fsUnderline;
  if (s) F->Style=F->Style<<fsStrikeOut;
}

void __fastcall LoadStrings (TStrings *S, FILE *fp)
{
  int n;
  S->Clear();
  fscanf (fp, "%d\n", &n);
  for (int i = 0; i < n; i++)
    S->Add(RS(fp));
}

void __fastcall StreamReadFont (TFileStream *fs, TFont* Fnt)
{
  DWORD Col;
  fs->Read(&Col,4);
  Fnt->Color = Col;
  fs->Read(&Col,4);
  Fnt->Size = Col;
  Fnt->Name=StreamString(fs);
  BYTE b=0,i=0,u=0,s=0;
  fs->Read(&b,1);
  fs->Read(&i,1);
  fs->Read(&u,1);
  fs->Read(&s,1);
  Fnt->Style=TFontStyles();
  if (b==1)
    Fnt->Style=Fnt->Style<<fsBold;
  if (i==1)
    Fnt->Style=Fnt->Style<<fsItalic;
  if (u==1)
    Fnt->Style=Fnt->Style<<fsUnderline;
  if (s==1)
    Fnt->Style=Fnt->Style<<fsStrikeOut;
}

void __fastcall FPWriteFont (FILE *fp, TFont *Font)
{
  fprintf (fp, "0x%s\n%d\n%s\n", IntToHex(Font->Color,6).c_str(), Font->Size, Font->Name.c_str());
  AnsiString A;
  if (Font->Style.Contains(fsBold))
    A+="b";
  if (Font->Style.Contains(fsItalic))
    A+="i";
  if (Font->Style.Contains(fsUnderline))
    A+="u";
  if (Font->Style.Contains(fsStrikeOut))
    A+="s";
  fprintf (fp, "%s\n", A.c_str());  
}

void __fastcall TMainForm::LoadSkin (AnsiString File)
{
  FILE *fp = fopen (File.c_str(),"r");
  int l,t,w,h;
  fscanf (fp, "%d\n%d\n", &w, &h);
  ClientWidth=w;
  ClientHeight=h;
  for (int i = 1; i < ltwhcn; i++)
  {
    fscanf (fp, "%d\n%d\n%d\n%d\n",&l,&t,&w,&h);
    LTWHControls[i]->Left=l;
    LTWHControls[i]->Top=t;
    LTWHControls[i]->Width=w;
    LTWHControls[i]->Height=h;
  }
  for (int i = 0; i < xbbn; i++)
  {
    fscanf (fp, "%d\n%d\n%d\n", &l, &t, &w);
    XPBitBtns[i]->BorderHeight=l;
    XPBitBtns[i]->Transparent=t==1;
    if (w==1)
      XPBitBtns[i]->NormalImage->LoadFromFile(ExtractFilePath(File)+RS(fp));
    else XPBitBtns[i]->NormalImage->FreeImage();
    XPBitBtns[i]->DisabledImage->Assign(XPBitBtns[i]->NormalImage);
    fscanf (fp, "%d\n", &w);
    XPBitBtns[i]->EnableHover=w==1;
    if (w==1)
      XPBitBtns[i]->HoverImage->LoadFromFile(ExtractFilePath(File)+RS(fp));
    else XPBitBtns[i]->HoverImage->Assign(XPBitBtns[i]->NormalImage);
    XPBitBtns[i]->PressedImage->LoadFromFile(ExtractFilePath(File)+RS(fp));
    fscanf (fp, "%d\n", &w);
    if (w==1)
      XPBitBtns[i]->DownImage->LoadFromFile(ExtractFilePath(File)+RS(fp));
    else XPBitBtns[i]->DownImage->FreeImage();
    fscanf (fp, "%d\n", &w);
    if (w==1)
      XPBitBtns[i]->Glyph->LoadFromFile(ExtractFilePath(File)+RS(fp));
    else XPBitBtns[i]->Glyph->FreeImage();
    fscanf (fp, "%d\n", &w);
    if (w==1)
      XPBitBtns[i]->DisabledGlyph->LoadFromFile(ExtractFilePath(File)+RS(fp));
    else XPBitBtns[i]->DisabledGlyph->FreeImage();
  }
  for (int i = 0; i < lcn; i++)
    LoadCaptions[i]->Caption=RS(fp);
  // -- SelDirBtn
  fscanf(fp, "%d\n", &w);
  if (w==1)
    ReadFont (SelDirBtn->HoverFont, fp);
  fscanf(fp, "%d\n", &w);
  if (w==1)
    ReadFont (SelDirBtn->PressedFont, fp);
  fscanf(fp, "%d\n", &w);
  if (w==1)
    ReadFont (SelDirBtn->Font, fp);
  SelDirBtn->Caption=RS(fp);
  // -- Back/Next Btns
  fscanf(fp, "%d\n", &w);
  if (w==1)
    ReadFont (BackBtn->DisabledFont, fp);
  fscanf(fp, "%d\n", &w);
  if (w==1)
  {
    ReadFont (BackBtn->HoverFont, fp);
    NextBtn->HoverFont->Assign(BackBtn->HoverFont);
  }
  fscanf(fp, "%d\n", &w);
  if (w==1)
  {
    ReadFont (BackBtn->PressedFont, fp);
    NextBtn->PressedFont->Assign(BackBtn->PressedFont);
  }
  fscanf(fp, "%d\n", &w);
  if (w==1)
  {
    ReadFont (BackBtn->Font, fp);
    NextBtn->Font->Assign(BackBtn->Font);
  }
  BackBtn->Caption=RS(fp);
  NextBtn->Caption=RS(fp);
  // -- THIS
  fscanf(fp, "%d\n", &w);
  if (w==1)
    ReadFont (Font, fp);
  fscanf(fp, "%d\n", &w);
  if (w==1)
    WindowI->Picture->LoadFromFile(ExtractFilePath(File)+RS(fp));
  // -- CloseBtn
  CloseBtn->NormalImage->LoadFromFile(ExtractFilePath(File)+RS(fp));
  CloseBtn->HoverImage->LoadFromFile(ExtractFilePath(File)+RS(fp));
  CloseBtn->PressedImage->LoadFromFile(ExtractFilePath(File)+RS(fp));
  fscanf(fp, "%d\n", &w);
  CloseBtn->EnableHover=w==1;
  fscanf(fp, "%d\n", &w);
  CloseBtn->Transparent=w==1;
  // -- MinimizeBtn
  MinimizeBtn->NormalImage->LoadFromFile(ExtractFilePath(File)+RS(fp));
  MinimizeBtn->HoverImage->LoadFromFile(ExtractFilePath(File)+RS(fp));
  MinimizeBtn->PressedImage->LoadFromFile(ExtractFilePath(File)+RS(fp));
  fscanf(fp, "%d\n", &w);
  MinimizeBtn->EnableHover=w==1;
  fscanf(fp, "%d\n", &w);
  MinimizeBtn->Transparent=w==1;
  // -- SideBar
  fscanf(fp, "%d\n", &w);
  if (w==1)
    SideBar->FutureIcon->LoadFromFile (ExtractFilePath(File)+RS(fp));
  fscanf(fp, "%d\n", &w);
  if (w==1)
    SideBar->CurrentIcon->LoadFromFile (ExtractFilePath(File)+RS(fp));
  fscanf(fp, "%d\n", &w);
  if (w==1)
    SideBar->CompleteIcon->LoadFromFile (ExtractFilePath(File)+RS(fp));
  fscanf(fp, "%d\n", &w);
  if (w==1)
    LoadStrings (SideBar->Items,fp);
  fscanf(fp, "%d\n", &w);
  if (w==1)
    ReadFont (SideBar->FutureFont,fp);
  // -- ProgressBar
  fscanf (fp, "%d\n", &w);
  switch (w)
  {
    case 0: ProgressBar->BevelType=vbNone; break;
    case 1: ProgressBar->BevelType=vbLowered; break;
    case 2: ProgressBar->BevelType=vbRaised; break;
  }
  fscanf (fp, "%d\n", &w);
  switch (w)
  {
    case 0: ProgressBar->GradientType=gtVertical; break;
    case 1: ProgressBar->GradientType=gtHorizontal; break;
  }
  ProgressBar->Color=StrToInt(RS(fp));
  ProgressBar->Color1=StrToInt(RS(fp));
  ProgressBar->Color2=StrToInt(RS(fp));
  // LicCheck
  LicCheck->NCNormal->LoadFromFile(ExtractFilePath(File)+RS(fp));
  LicCheck->NCHover->LoadFromFile(ExtractFilePath(File)+RS(fp));
  LicCheck->NCDown->LoadFromFile(ExtractFilePath(File)+RS(fp));
  LicCheck->CNormal->LoadFromFile(ExtractFilePath(File)+RS(fp));
  LicCheck->CHover->LoadFromFile(ExtractFilePath(File)+RS(fp));
  LicCheck->CDown->LoadFromFile(ExtractFilePath(File)+RS(fp));
  LicCheck->Caption=RS(fp);
  // Scrollbars (LicScroll,FeatureScroll,ShortScroll)
  LicScroll->BorderHeight = StrToInt(RS(fp));
  FeatureScroll->BorderHeight = LicScroll->BorderHeight;
  ShortScroll->BorderHeight = LicScroll->BorderHeight;
  LicScroll->Shaft->LoadFromFile(ExtractFilePath(File)+RS(fp));
  LicScroll->UpNormal->LoadFromFile(ExtractFilePath(File)+RS(fp));
  LicScroll->UpHover->LoadFromFile(ExtractFilePath(File)+RS(fp));
  LicScroll->UpDown->LoadFromFile(ExtractFilePath(File)+RS(fp));
  LicScroll->DownNormal->LoadFromFile(ExtractFilePath(File)+RS(fp));
  LicScroll->DownHover->LoadFromFile(ExtractFilePath(File)+RS(fp));
  LicScroll->DownDown->LoadFromFile(ExtractFilePath(File)+RS(fp));
  LicScroll->ThumbNormal->LoadFromFile(ExtractFilePath(File)+RS(fp));
  LicScroll->ThumbHover->LoadFromFile(ExtractFilePath(File)+RS(fp));
  LicScroll->ThumbDown->LoadFromFile(ExtractFilePath(File)+RS(fp));
  ShortScroll->Shaft->Assign(LicScroll->Shaft);
  ShortScroll->UpNormal->Assign(LicScroll->UpNormal);
  ShortScroll->UpHover->Assign(LicScroll->UpHover);
  ShortScroll->UpDown->Assign(LicScroll->UpDown);
  ShortScroll->DownNormal->Assign(LicScroll->DownNormal);
  ShortScroll->DownHover->Assign(LicScroll->DownHover);
  ShortScroll->DownDown->Assign(LicScroll->DownDown);
  ShortScroll->ThumbNormal->Assign(LicScroll->ThumbNormal);
  ShortScroll->ThumbHover->Assign(LicScroll->ThumbHover);
  ShortScroll->ThumbDown->Assign(LicScroll->ThumbDown);
  FeatureScroll->Shaft->Assign(LicScroll->Shaft);
  FeatureScroll->UpNormal->Assign(LicScroll->UpNormal);
  FeatureScroll->UpHover->Assign(LicScroll->UpHover);
  FeatureScroll->UpDown->Assign(LicScroll->UpDown);
  FeatureScroll->DownNormal->Assign(LicScroll->DownNormal);
  FeatureScroll->DownHover->Assign(LicScroll->DownHover);
  FeatureScroll->DownDown->Assign(LicScroll->DownDown);
  FeatureScroll->ThumbNormal->Assign(LicScroll->ThumbNormal);
  FeatureScroll->ThumbHover->Assign(LicScroll->ThumbHover);
  FeatureScroll->ThumbDown->Assign(LicScroll->ThumbDown);
  // -- Trees
  ShortcutTree->Color=StrToInt(RS(fp));
  FeatureTree->Color=ShortcutTree->Color;
  ShortcutTree->LinesColor=StrToInt(RS(fp));
  FeatureTree->LinesColor=ShortcutTree->LinesColor;
  fclose (fp);
}
void __fastcall TMainForm::FormDestroy(TObject *Sender)
{
  delete NFeats;
  delete MFeats;
  delete DFeats;
  delete RFeats;
  for (int i = 0; i < SFeats->Count; i++)
  {
    delete FeatsFiles[i];
    delete FeatsShs[i];
    delete FeatsSms[i];
    delete FeatsSds[i];
  }
  delete SFeats;
  delete [] FeatsSizes;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::DecompileIntoFolder (AnsiString File, AnsiString Dir)
{
  if (Dir[Dir.Length()]!='\\')
    Dir+='\\';
  FILE *fp = fopen ((Dir+ChangeFileExt(ExtractFileName(File),".vts")).c_str(),"w");
  TFileStream *fs = new TFileStream (File, fmOpenRead);
  char *sign = new char [4];
  fs->Read(sign,3);
  if (sign[0]!='V'||sign[1]!='S'||sign[2]!='F')
  {
    Application->MessageBoxA("Этот файл не является файлом VMX Skin","Ошибка",MB_OK|MB_ICONERROR);
    return;
  }
  int l, t, w, h;
  fs->Read(&w,4);
  fs->Read(&h,4);
  fprintf(fp,"%d\n%d\n",w,h);
  for (int i = 1; i < 47; i++)
  {
    fs->Read(&l,4);
    fs->Read(&t,4);
    fs->Read(&w,4);
    fs->Read(&h,4);
    fprintf(fp,"%d\n%d\n%d\n%d\n",l,t,w,h);
  }
  BYTE bol;
  int AA;
  for (int i = 0; i < 9; i++)
  {
    fs->Read(&AA,4);
    fs->Read(&bol,1);
    fprintf(fp,"%d\n%d\n",AA,(int)bol);
    fs->Read(&bol,1);
    fprintf(fp,"%d\n",(int)bol);
    if (bol==1)
    {
      __int64 len;
      fs->Read(&len,8);
      TFileStream *f2 = new TFileStream (Dir+"Btn"+IntToStr(i)+"Normal.bmp",fmOpenWrite|fmCreate);
      f2->CopyFrom(fs,len);
      delete f2;
      fprintf(fp,"%s\n",("Btn"+IntToStr(i)+"Normal.bmp").c_str());
    }
    fs->Read(&bol,1);
    fprintf(fp,"%d\n",(int)bol);
    if (bol==1)
    {
      __int64 len;
      fs->Read(&len,8);
      TFileStream *f2 = new TFileStream (Dir+"Btn"+IntToStr(i)+"Hover.bmp",fmOpenWrite|fmCreate);
      f2->CopyFrom(fs,len);
      delete f2;
      fprintf(fp,"%s\n",("Btn"+IntToStr(i)+"Hover.bmp").c_str());
    }
    __int64 len;
    fs->Read(&len,8);
    TFileStream *f2 = new TFileStream (Dir+"Btn"+IntToStr(i)+"Pressed.bmp",fmOpenWrite|fmCreate);
    f2->CopyFrom(fs,len);
    delete f2;
    fprintf(fp,"%s\n",("Btn"+IntToStr(i)+"Pressed.bmp").c_str());
    fs->Read(&bol,1);
    fprintf(fp,"%d\n",(int)bol);
    if (bol==1)
    {
      __int64 len;
      fs->Read(&len,8);
      TFileStream *f2 = new TFileStream (Dir+"Btn"+IntToStr(i)+"Down.bmp",fmOpenWrite|fmCreate);
      f2->CopyFrom(fs,len);
      delete f2;
      fprintf(fp,"%s\n",("Btn"+IntToStr(i)+"Down.bmp").c_str());
    }
    fs->Read(&bol,1);
    fprintf(fp,"%d\n",(int)bol);
    if (bol==1)
    {
      __int64 len;
      fs->Read(&len,8);
      TFileStream *f2 = new TFileStream (Dir+"Btn"+IntToStr(i)+"Glyph.bmp",fmOpenWrite|fmCreate);
      f2->CopyFrom(fs,len);
      delete f2;
      fprintf(fp,"%s\n",("Btn"+IntToStr(i)+"Glyph.bmp").c_str());
    }
    fs->Read(&bol,1);
    fprintf(fp,"%d\n",(int)bol);
    if (bol==1)
    {
      __int64 len;
      fs->Read(&len,8);
      TFileStream *f2 = new TFileStream (Dir+"Btn"+IntToStr(i)+"DisGlyph.bmp",fmOpenWrite|fmCreate);
      f2->CopyFrom(fs,len);
      delete f2;
      fprintf(fp,"%s\n",("Btn"+IntToStr(i)+"DisGlyph.bmp").c_str());
    }
  }
  for (int i = 0; i < 21; i++)
    fprintf(fp,"%s\n",StreamString(fs).c_str());
  // SelDirBtn
  fs->Read(&bol,1);
  fprintf(fp,"%d\n",(int)bol);
  TFont *Tmp = new TFont;
  if (bol==1)
  {
    StreamReadFont(fs,Tmp);
    FPWriteFont(fp,Tmp);
  }
  fs->Read(&bol,1);
  fprintf(fp,"%d\n",(int)bol);
  if (bol==1)
  {
    StreamReadFont(fs,Tmp);
    FPWriteFont(fp,Tmp);
  }
  fs->Read(&bol,1);
  fprintf(fp,"%d\n",(int)bol);
  if (bol==1)
  {
    StreamReadFont(fs,Tmp);
    FPWriteFont(fp,Tmp);
  }
  fprintf(fp,"%s\n",StreamString(fs).c_str());
  // BackNextBtns
  fs->Read(&bol,1);
  fprintf(fp,"%d\n",(int)bol);
  if (bol==1)
  {
    StreamReadFont(fs,Tmp);
    FPWriteFont(fp,Tmp);
  }
  fs->Read(&bol,1);
  fprintf(fp,"%d\n",(int)bol);
  if (bol==1)
  {
    StreamReadFont(fs,Tmp);
    FPWriteFont(fp,Tmp);
  }
  fs->Read(&bol,1);
  fprintf(fp,"%d\n",(int)bol);
  if (bol==1)
  {
    StreamReadFont(fs,Tmp);
    FPWriteFont(fp,Tmp);
  }
  fs->Read(&bol,1);
  fprintf(fp,"%d\n",(int)bol);
  if (bol==1)
  {
    StreamReadFont(fs,Tmp);
    FPWriteFont(fp,Tmp);
  }
  fprintf(fp,"%s\n",StreamString(fs).c_str());
  fprintf(fp,"%s\n",StreamString(fs).c_str());
  // This
  fs->Read(&bol,1);
  fprintf(fp,"%d\n",(int)bol);
  if (bol==1)
  {
    StreamReadFont(fs,Tmp);
    FPWriteFont(fp,Tmp);
  }
  fs->Read(&bol,1);
  fprintf(fp,"%d\n",(int)bol);
  if (bol==1)
  {
    __int64 len;
    fs->Read(&len,8);
    TFileStream *f2 = new TFileStream (Dir+"MainImage.bmp.tmp",fmOpenWrite|fmCreate);
    f2->CopyFrom(fs,len);
    delete f2;
    UclDecompressFile (Dir+"Mainimage.bmp.tmp",Dir+"Mainimage.bmp");
    remove ((Dir+"Mainimage.bmp.tmp").c_str());
    fprintf(fp,"%s\n","MainImage.bmp");
  }
  // CloseBtn
  __int64 len;
  fs->Read(&len,8);
  TFileStream *f2 = new TFileStream (Dir+"CBN.bmp",fmOpenWrite|fmCreate);
  f2->CopyFrom(fs,len);
  delete f2;
  fprintf(fp,"%s\n","CBN.bmp");
  fs->Read(&len,8);
  f2 = new TFileStream (Dir+"CBO.bmp",fmOpenWrite|fmCreate);
  f2->CopyFrom(fs,len);
  delete f2;
  fprintf(fp,"%s\n","CBO.bmp");
  fs->Read(&len,8);
  f2 = new TFileStream (Dir+"CBP.bmp",fmOpenWrite|fmCreate);
  f2->CopyFrom(fs,len);
  delete f2;
  fprintf(fp,"%s\n","CBP.bmp");
  fs->Read(&bol,1);
  fprintf(fp,"%d\n",(int)bol);
  fs->Read(&bol,1);
  fprintf(fp,"%d\n",(int)bol);
  // MinimizeBtn
  fs->Read(&len,8);
  f2 = new TFileStream (Dir+"MBN.bmp",fmOpenWrite|fmCreate);
  f2->CopyFrom(fs,len);
  delete f2;
  fprintf(fp,"%s\n","MBN.bmp");
  fs->Read(&len,8);
  f2 = new TFileStream (Dir+"MBO.bmp",fmOpenWrite|fmCreate);
  f2->CopyFrom(fs,len);
  delete f2;
  fprintf(fp,"%s\n","MBO.bmp");
  fs->Read(&len,8);
  f2 = new TFileStream (Dir+"MBP.bmp",fmOpenWrite|fmCreate);
  f2->CopyFrom(fs,len);
  delete f2;
  fprintf(fp,"%s\n","MBP.bmp");
  fs->Read(&bol,1);
  fprintf(fp,"%d\n",(int)bol);
  fs->Read(&bol,1);
  fprintf(fp,"%d\n",(int)bol);
  // Sidebar
  fs->Read(&bol,1);
  fprintf(fp,"%d\n",(int)bol);
  if (bol==1)
    fprintf(fp,"%s\n",StreamString(fs).c_str());
  fs->Read(&bol,1);
  fprintf(fp,"%d\n",(int)bol);
  if (bol==1)
    fprintf(fp,"%s\n",StreamString(fs).c_str());
  fs->Read(&bol,1);
  fprintf(fp,"%d\n",(int)bol);
  if (bol==1)
    fprintf(fp,"%s\n",StreamString(fs).c_str());
  fs->Read(&bol,1);
  fprintf(fp,"%d\n",(int)bol);
  if (bol==1)
    fprintf(fp,"%s\n",StreamString(fs).c_str());
  fs->Read(&bol,1);
  fprintf(fp,"%d\n",(int)bol);
  if (bol==1)
  {
    StreamReadFont (fs,Tmp);
    FPWriteFont(fp,Tmp);
  }
  // Progressbar
  int AAA,BBB;
  fs->Read(&AAA,4);
  fs->Read(&BBB,4);
  fprintf (fp,"%d\n%d\n", AAA, BBB);
  DWORD Col;
  fs->Read(&Col,4);
  fprintf (fp,"%d\n",Col);
  fs->Read(&Col,4);
  fprintf (fp,"%d\n",Col);
  fs->Read(&Col,4);
  fprintf (fp,"%d\n",Col);
  // LicCheck
  fs->Read(&len,8);
  f2 = new TFileStream (Dir+"NCN.bmp",fmOpenWrite|fmCreate);
  f2->CopyFrom(fs,len);
  delete f2;
  fprintf(fp,"%s\n","NCN.bmp");
  fs->Read(&len,8);
  f2 = new TFileStream (Dir+"NCO.bmp",fmOpenWrite|fmCreate);
  f2->CopyFrom(fs,len);
  delete f2;
  fprintf(fp,"%s\n","NCO.bmp");
  fs->Read(&len,8);
  f2 = new TFileStream (Dir+"NCP.bmp",fmOpenWrite|fmCreate);
  f2->CopyFrom(fs,len);
  delete f2;
  fprintf(fp,"%s\n","NCP.bmp");
  fs->Read(&len,8);
  f2 = new TFileStream (Dir+"CN.bmp",fmOpenWrite|fmCreate);
  f2->CopyFrom(fs,len);
  delete f2;
  fprintf(fp,"%s\n",("CN.bmp"));
  fs->Read(&len,8);
  f2 = new TFileStream (Dir+"CO.bmp",fmOpenWrite|fmCreate);
  f2->CopyFrom(fs,len);
  delete f2;
  fprintf(fp,"%s\n",("CO.bmp"));
  fs->Read(&len,8);
  f2 = new TFileStream (Dir+"CP.bmp",fmOpenWrite|fmCreate);
  f2->CopyFrom(fs,len);
  delete f2;
  fprintf(fp,"%s\n",("CP.bmp"));
  fprintf(fp,"%s\n",StreamString(fs).c_str());
  // Scrollbars
  fs->Read(&Col,4);
  fprintf(fp,"%d\n",Col);
  fs->Read(&len,8);
  f2 = new TFileStream (Dir+"fb.bmp",fmOpenWrite|fmCreate);
  f2->CopyFrom(fs,len);
  delete f2;
  fprintf(fp,"%s\n",("fb.bmp"));
  fs->Read(&len,8);
  f2 = new TFileStream (Dir+"fun.bmp",fmOpenWrite|fmCreate);
  f2->CopyFrom(fs,len);
  delete f2;
  fprintf(fp,"%s\n",("fun.bmp"));
  fs->Read(&len,8);
  f2 = new TFileStream (Dir+"fuo.bmp",fmOpenWrite|fmCreate);
  f2->CopyFrom(fs,len);
  delete f2;
  fprintf(fp,"%s\n",("fuo.bmp"));
  fs->Read(&len,8);
  f2 = new TFileStream (Dir+"fup.bmp",fmOpenWrite|fmCreate);
  f2->CopyFrom(fs,len);
  delete f2;
  fprintf(fp,"%s\n",("fup.bmp"));
  fs->Read(&len,8);
  f2 = new TFileStream (Dir+"fdn.bmp",fmOpenWrite|fmCreate);
  f2->CopyFrom(fs,len);
  delete f2;
  fprintf(fp,"%s\n",("fdn.bmp"));
  fs->Read(&len,8);
  f2 = new TFileStream (Dir+"fdo.bmp",fmOpenWrite|fmCreate);
  f2->CopyFrom(fs,len);
  delete f2;
  fprintf(fp,"%s\n",("fdo.bmp"));
  fs->Read(&len,8);
  f2 = new TFileStream (Dir+"fdp.bmp",fmOpenWrite|fmCreate);
  f2->CopyFrom(fs,len);
  delete f2;
  fprintf(fp,"%s\n",("fdp.bmp"));
  fs->Read(&len,8);
  f2 = new TFileStream (Dir+"fgn.bmp",fmOpenWrite|fmCreate);
  f2->CopyFrom(fs,len);
  delete f2;
  fprintf(fp,"%s\n",("fgn.bmp"));
  fs->Read(&len,8);
  f2 = new TFileStream (Dir+"fgo.bmp",fmOpenWrite|fmCreate);
  f2->CopyFrom(fs,len);
  delete f2;
  fprintf(fp,"%s\n",("fgo.bmp"));
  fs->Read(&len,8);
  f2 = new TFileStream (Dir+"fgp.bmp",fmOpenWrite|fmCreate);
  f2->CopyFrom(fs,len);
  delete f2;
  fprintf(fp,"%s\n",("fgp.bmp"));
  // Trees
  fs->Read(&Col,4);
  fprintf(fp,"%d\n",Col);
  fs->Read(&Col,4);
  fprintf(fp,"%d\n",Col);
  delete fs;
  fclose (fp);
  delete Tmp;
}
