unit UnitMisc;

interface

uses sysutils, HexUtils, classes, Windows, boots, dialogs ;

type TPhInfoRecord = record
     Name:string;
     PhType:string;
     Model:string;
     MCUSW:string;
     PPMInfo:string;
     HWID:string;
     PCI:string;
     APETest:string;
     RFIC:string;
     DSP:string;
     APECoreSW:string;
     APEVariant:string;
     Retu:string;
     Tahvo:string;
     CNT : string;
     APEHW:string;
     APEADSPSW:string;
     LSN:string;
     APEBT:string;
     PrdSerial:string;
     ProductCode:string;
     ModuleCode:string;
     BisicPrdCode:string;
     IMEIPlain:string;
     IMEI2Net:string;
     IMEISv2Net:string;
     Bat:string;
     Cam:string;
     CMTbtver:string;
     LCD:string;
     FLic:string;
     CRR:string; //результат сброса кода на дефолтный
     PrdCok:string; // результат записи продукт кода. Стоит перманентный - проверка реализована в коде.
     APEic:string;
     end;


type TRPLRecord = record
     NPC:string;
     CCC:string;
     HWC:string;
     SIMLOCK:string;
     SIMLOCK_KEY:string;
     SUPERDONGLE_KEY:string;
     CMLA_KEY:string;
     WMDRM_PD:string;
     Variant:string;
     end;

type TUkeyData  = record
     Hash:string;
     PID:string;
     Key:string;
     end;


function PhModeToStr (mode:integer):string ;
function rawtotemp(raw:Integer):string;
function PathConv(path:string):string;
function FindDescr(filename:string):string ;
function FindNam(filename:string):boolean ;
procedure repairdata();
function getkeycode(kw:Word):string;
function getkeystatus(data:Word):string;
function SelLoaders(IdR:string):boolean;
function affenabled():Boolean;
function SecondToTime(const Seconds: Cardinal): Double;
function showtime(time:cardinal):string;
procedure endtimecount();
procedure starttime();
function FbusSelLoader2nd(IdR:string):boolean;
function Select2ndDie(idr:string):Boolean;
function NextPos(SearchStr, Str: string; Position: Integer): Integer;
function LastPos(SearchStr, Str: string): Integer;
function getsub(b:byte):string;
function getasic(b:byte):string;
procedure UkeyClear();
function convertimages40(imname:string):boolean;
function checkcnt(imname:string):integer;

var
  RPLRecord         :TRPLRecord;
  PhInfoRecord      :TPhInfoRecord;
  UkeyData          :TUkeyData;
  Smart             :boolean;
  ConMode           :integer; //0=USB, 1=COM, 2=...
  RM:string;
  typeinf,Generation,
  Crypted,datapos   :string;
  fileexist         :Boolean;
  currproduct       :string;
  M                 :TMemoryStream;
  zad               :Integer;
  TypePHstr         :string;
  csbyte1,csbyte2,
  csbyte3,csbyte4   :Byte;
  SWver             :string;
  Floader,Sloader   :string;
  StartDir          :string;
  tmsstart,tmsstop,
  tmsres, opstart,
  opend             :Cardinal;
  directmode        :Boolean;
  apeexist          :Boolean;
  FbusFloader,
  FbusSloader       :string;
  FASICcmt, FASICape:string;
  cmd_buf           :array[0..$FFFF] of byte;
  algo              :string;
  fbdev             :integer;
  fbnum             :string;
  devbyte           :Byte;
  ROOTKEY           :string;
  boot_done         :Boolean;
  imei_global       :string;
  bof               :integer;
  furCMT            :byte;
  FLtype            :string;
  UFsretry          :Integer;
  flven             :DWORD;
  stop,operation    :Boolean;
  ppmlang,
  ppm1lang,
  s1ppm             :string;
  ppmselect,
  ppm1select        :Boolean;
  flicven           :DWORD;
  sltststart,
  sltstsend         :Integer;
  ltdata            :integer;
  psi               :string;

  DataHeader : array [0..53] of Byte =
  ($F1, $00, $21, $00, $03, $D1, $12, $4A, $6F, $72, $6E, $61, $64, $61, $20, $44, $65, $6C, $20, $4D, $75, $65, $72, $74, $6F, $DD, $17, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $FC, $02, $00, $00);

  dataheader2: array[0..53] of byte = (
	$F1, $00, $21, $00, $03, $D1, $12, $53, $65, $72, $69, $65, $73, $20, $34, $30, 
	$20, $52, $65, $73, $74, $6F, $72, $65, $20, $DD, $17, $00, $00, $00, $00, $00, 
	$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, 
	$00, $00, $FC, $02, $00, $00);

  Zerobyte : Widestring = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'+
'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'+
'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'+
'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'+
'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'+
'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'+
'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';

implementation
uses Unit1, forms, UsbMain, UnitE1, UContent ;
const
  SecPerDay = 86400;
  SecPerHour = 3600;
  SecPerMinute = 60;

function SecondToTime(const Seconds: Cardinal): Double;
var    
  ms, ss, mm, hh, dd: Cardinal;    
begin    
  dd := Seconds div SecPerDay;
  hh := (Seconds mod SecPerDay) div SecPerHour;    
  mm := ((Seconds mod SecPerDay) mod SecPerHour) div SecPerMinute;
  ss := ((Seconds mod SecPerDay) mod SecPerHour) mod SecPerMinute;    
  ms := 0;    
  Result :=EncodeTime(hh, mm, ss, ms);    
end;

function Select2ndDie(idr:string):Boolean;
var
  s:string;
begin
  result:=true;
  idr:=copy(idr,1,5);
  FbusFloader:='';
  FbusSloader:='';
  case Str2Byte(idr[1]+idr[2]) of
  $BA:
  begin
  FbusFloader:=StartDir+'Flash\UFS\Special\RAP3Gv3_BA';
  FbusSloader:=StartDir+'Flash\UFS\Special\Cboot_BA';
  bof:=2;
  end;
  $9D:
  begin
  FbusFloader:=StartDir+'Flash\UFS\Special\RAP3Gv3_9D';
  FbusSloader:=StartDir+'Flash\UFS\Special\Cboot_9D';
  bof:=2;
  end;
  $E9:
  begin
  FbusFloader:=StartDir+'Flash\UFS\Special\RAP3Gv2_E9';
  FbusSloader:=StartDir+'Flash\UFS\Special\Cboot_E9';
  bof:=1;
  end;
  $38:
  begin
  FbusFloader:=StartDir+'Flash\UFS\Special\RAP3Gv3_38';
  FbusSloader:=StartDir+'Flash\UFS\Special\Cboot_38';
  bof:=2;
  end;
  $A5:
  begin
  FbusFloader:=StartDir+'Flash\UFS\Special\RAP3Gv3_A5';
  FbusSloader:=StartDir+'Flash\UFS\Special\Cboot_A5';
  bof:=3;
  end;
  $9A:
  begin
  FbusFloader:=StartDir+'Flash\UFS\Special\RAPIDO_9A';
  FbusSloader:=StartDir+'Flash\UFS\Special\Cboot_9A';
  bof:=3;
  end;
  $CA:
  begin
  FbusFloader:=StartDir+'Flash\UFS\Special\RAPIDO_CA';
  FbusSloader:=StartDir+'Flash\UFS\Special\Cboot_CA';
  bof:=3;
  end;
  $F2:
   begin
   FbusFloader:=StartDir+'Flash\UFS\Special\RAPIDO_F2';
   FbusSloader:=StartDir+'Flash\UFS\Special\Cboot_F2';
   bof:=3;
   end;
  $F6:
  begin
  FbusFloader:=StartDir+'Flash\UFS\Special\RAPIDO_F6';
  FbusSloader:=StartDir+'Flash\UFS\Special\Cboot_F6';
  bof:=3;
  end;
  $FC:
  begin
  FbusFloader:=StartDir+'Flash\UFS\Special\RAPIDO_FC';
  FbusSloader:=StartDir+'Flash\UFS\Special\Cboot_FC';
  bof:=3;
  end;

  else result:=False;
 end;
end;

function SelLoaders(IdR:string):boolean;
var s,s1,s3,s4,ss:string;
begin
   Result:=false;
   Floader:='';
   Sloader:='';
   if Pos (IdR,'0003192103002107000C1921030021070003192103012107000C192103012107000C1921030221070003192103022107')<>0 then begin
     Floader:=StartDir+'Flash\RAPUv21_2nd.fg';
     Sloader:=StartDir+'Flash\RAPUv21_XSR17_alg.fg';
     Result:=true;
     exit;
   end;
   if Pos (IdR,'4003192102001104400C1921020011046003192102001104600C1921020011046003192102011104600C1921020111046003192102021104600C1921020211046003192102031104600C192102031104')<>0 then begin
     Floader:=StartDir+'Flash\RAPUv11_2nd.fg';
     Sloader:=StartDir+'Flash\RAPUv11_XSR17_alg.fg';
     Result:=true;
     exit;
   end;
   s:='0203192102004000020C1921020040000203192102024000020C192102024000020C1921020041000203192102004100020C1921020141000203192102014100020C1921020140000203192102014000';
   s1:='020C19210203400002031921020340000203192102024100020C1921020241000203192102034100020C1921020341000203192102054100020C1921020541000203192102044100020C192102044100';
   s:=s+s1;
   if Pos (IdR,s)<>0 then begin
     Floader:=StartDir+'Flash\RAP3Gv40_2nd.fg';
     Sloader:=StartDir+'Flash\RAP3Gv40_XSR17_alg.fg';
     Result:=true;
     exit;
   end;
   if Pos (IdR,'22000209200C0000220002092003000022000509200C00002200050920030000')<>0 then begin
     Floader:=StartDir+'Flash\BCM21351_usb2nd.fg';
     Sloader:=StartDir+'Flash\BCM21351_XSR16_usbalg.fg';
     Result:=true;
     exit;
   end;

  { s3:='0103192101003000010C1921010030000103192101013000010C1921010130000103192101003100010C1921010031000303192101023000030C1921010230000303192101033000030C1921010330000003192101002000000C1921010020000003192101002100000C1921010021000003192101002200000C1921010022';
   s4:='000003192101012200000C1921010122000103192101001101010C1921010011010003192101001002000C1921010010020013192101001002001C192101001002';
   ss:=s3+s4;
   if Pos (IdR,ss)<>0 then begin
     Floader:=StartDir+'Flash\RAP3Gv30_2nd.fg';
     Sloader:=StartDir+'Flash\RAP3Gv30_XSR14_alg.fg';
     Result:=true;
     exit;
   end;  }
end;

function PathConv(path:string):string;
var
Len:integer;
s:string;
sw:WideString;
begin
          sw:=UTF8Decode(path);
          Len:=(Length(sw) shl 1)+2;
          Result:='';
          s:='';
          SetLength(s,2);
          word ((@s[1])^):=Len;
          WordSwap(@s[1]);
          SetLength(Result,Len+2);
          BufCopySwapWord(@sw[1],@Result[1],Len);
          Result:=s+Result;
end;

function PhModeToStr (mode:integer):string ;
begin
        case mode of
        0 : Result := 'PowerOFF';
        1 : Result := 'Normal';
        2 : Result := 'Charging';
        3 : Result := 'Alarm';
        4 : Result := 'Test';
        5 : Result := 'Local';
        6 : Result := 'Warranty';
        7 : Result := 'Reliability';
        8 : Result := 'SelftestFail';
        9 : Result := 'SwDl';
       10 : Result := 'RfInactive';
       11 : Result := 'IdWrite';
       12 : Result := 'Discharging';
       13 : Result := 'SwReset';
        end;
end;

function rawtotemp(raw:Integer):string;
var
temp:integer;
begin
   case raw of
                // temperature from raw
570..579:temp:=0;
560..569:temp:=1;
550..559:temp:=2;
540..549:temp:=3;
530..539:temp:=4;
520..529:temp:=5;
510..519:temp:=6;
500..509:temp:=7;
490..499:temp:=8;
480..489:temp:=9;
470..479:temp:=10;
460..469:temp:=11;
450..459:temp:=12;
440..449:temp:=13;
430..439:temp:=14;
420..429:temp:=15;
410..419:temp:=16;
400..409:temp:=17;
390..399:temp:=18;
380..389:temp:=19;
370..379:temp:=20;
360..369:temp:=21;
350..359:temp:=22;
340..349:temp:=23;
330..339:temp:=24;
320..329:temp:=25;
310..319:temp:=26;
300..309:temp:=27;
290..299:temp:=28;
280..289:temp:=29;
270..279:temp:=30;
260..269:temp:=31;
250..259:temp:=32;
240..249:temp:=33;
230..239:temp:=34;
220..229:temp:=35;
210..219:temp:=36;
200..209:temp:=37;
190..199:temp:=38;
180..189:temp:=39;
170..179:temp:=40;
160..169:temp:=41;
150..159:temp:=42;
140..149:temp:=43;
130..139:temp:=44;
120..129:temp:=45;
110..119:temp:=46;
100..109:temp:=47;
90..99:temp:=48;
80..89:temp:=49;
70..79:temp:=50;
60..69:temp:=51;
50..59:temp:=52;
40..49:temp:=53;
30..39:temp:=54;
20..29:temp:=55;
10..19:temp:=56;
0..9:temp:=57
else temp:=0;
               end;
          Result:=inttostr(temp)+' C';
end;

function FindNam(filename:string):boolean ;
Label vp1;
var
Fn: System.Text;
s,name,styp:string;
i:integer;
begin
       Result:=false;
       System.Assign (Fn , filename) ;
       System.Reset (Fn);
       while not EOF(Fn) do begin
       System.Readln(Fn,s);
       if Pos('<File>',s)<>0 then begin
       System.Readln(Fn,s);
         while Pos('</File>',s)=0 do begin
           if Pos ('<Name>',s)<> 0 then begin
              name:='';
              i:=Pos ('<Name>',s);
              i:=i+6;
              while s[i] <> '<' do begin name:=name+s[i]; i:=i+1 end;
           end;
           if Pos ('<FileSubType>',s)<> 0 then begin
              styp:='';
              i:=Pos ('<FileSubType>',s);
              i:=i+13;
              while s[i] <> '<' do begin styp:=styp+s[i]; i:=i+1 end;
               if styp='Mcu' then core:=name;
               if styp='Ppm' then if ppm<>'' then ppm1:=name else ppm:=name;

               if styp='Content' then if image<>'' then begin
                if ape<>'' then cnt3:=name else ape:=name;
               end else image:=name;
           end;
vp1:
          System.Readln(Fn,s);
         end;
       end;
       end;
       System.Close(Fn);
      if core<>'' then Result:=true;
end;

function FindDescr(filename:string):string ;
var
Fn: System.Text;
s,ProdName,ProdCode,ProdVer,orFN:string;
i:integer;
begin
       SWver:='';
       Result:='';
       ProdName:='';
       ProdCode:='';
       ProdVer:='';
       orFN:='';
       System.Assign (Fn , filename) ;
       System.Reset (Fn);
       while not EOF(Fn) do begin
       System.Readln(Fn,s);
       if Pos('<Description>',s)<>0 then begin
          i:= Pos('<Description>',s);
          i:=i+13;
          while s[i] <> '<' do begin ProdName:=ProdName+s[i]; i:=i+1 end;
       end;
       if Pos('<ProductCode>',s)<>0 then begin
          i:= Pos('<ProductCode>',s);
          i:=i+13;
          while s[i] <> '<' do begin ProdCode:=ProdCode+s[i]; i:=i+1 end;
       end;
       if Pos('<SwVersion>',s)<>0 then begin
          i:= Pos('<SwVersion>',s);
          i:=i+11;
          while s[i] <> '<' do begin ProdVer:=ProdVer+s[i]; i:=i+1 end;
       end;
       {if Pos('<OriginalFileName>',s)<>0 then begin
          i:= Pos('<OriginalFileName>',s);
          i:=i+18;
          while s[i] <> '<' do begin orFN:=OrFN+s[i]; i:=i+1 end; 

       end;}
       end;
       System.Close(Fn);
       Result:=ProdCode+' '+ProdName+' ver '+ProdVer ;
       if ProdVer<>'' then SWver:=Prodver;
end;


procedure repairdata();
begin
  GETRoot[9]:=$01;
  GetBlock[7]:=$0D;
  GetBlock[8]:=$00;
  GetBlock[9]:=$0E;
end;

function getkeycode(kw:Word):string;
begin
  case kw of
  $0030:result:='0 [DIGIT]';
  $0031:result:='1 [DIGIT]';
  $0032:result:='2 [DIGIT]';
  $0033:result:='3 [DIGIT]';
  $0034:result:='4 [DIGIT]';
  $0035:result:='5 [DIGIT]';
  $0036:result:='6 [DIGIT]';
  $0037:result:='7 [DIGIT]';
  $0038:result:='8 [DIGIT]';
  $0039:result:='9 [DIGIT]';
  $0023:result:='#';
  $002A:result:='*';
  $E001:result:='PWR';
  $E003:result:='LSoft';
  $E004:result:='RSoft';
  $E005:result:='SEND';
  $E006:result:='END';
  $E007:result:='UP';
  $E008:result:='DOWN';
  $E00A:result:='VOL+';
  $E00B:result:='VOL-';
  $E00C:result:='OK';
  $E00D:result:='LEFT';
  $E00E:result:='RIGHT';
  $0E5C:result:='CAM';
  $0008:result:='Clear [C]';
  $F852:result:='Menu';
  $F884:result:='Pen';
  $F842:result:='LSoft';
  $F843:result:='RSoft';
  $F80A:result:='DOWN';
  $F809:result:='UP';
  $F808:result:='RIGHT';
  $F807:result:='LEFT';
  $F883:result:='CAM';
  $F88F:result:='CPrew';
  $F881:result:='Fplay';
  $F886:result:='FfW';
  $F880:result:='FRew';
  $F845:result:='Ok/Select' ;
  $F863:result:='END';
  $E05C:result:='CAM';
  $E05D:result:='CFocus';
  $F862:result:='SEND';
  $E060:result:='Play/Pause';
  $E061:result:='Play[Rewind]';
  $E05F:result:='Play[Forward]';
  $F856:result:='Play[Forward]';
  $F854:result:='Play[Play/Pause]';
  $F855:result:='Play[Stop]';
  $F857:result:='Play[Rewind]';
  $F847:result:='Slide[Down]';
  $F84A:result:='Slide[Down|PlayMode]';
  $F84B:result:='Slide[Up|Close]';
  $F846:result:='Slide[Up|Open]';
  $F80B:result:='Pen';
  $F858:result:='MMedia key';
  $F840:result:='VOL+';
  $F841:result:='VOL-';
  $F887:result:='Camera Lens open';
  $F888:result:='Camera Lens close';
  $E002:result:='Slide Open/Close';
  else result:='UNKNOW KEY';
  end;
end;

function getkeystatus(data:Word):string;
begin
  case data of
  $000D:result:='Press, long press, repeat';
  $000F:result:='Press, Release, Long press, repeat';
  $0003:result:='Press, Release';
  $0001:result:='Press';
  $0007:result:='Press, Release, Long press';
  $0083:result:='Press, Release';
  $0010:result:='Slide up';
  $0020:result:='Slide down';
  $0030:result:='Slide down/up';
  $0048:result:='Slide down/up many times';
  //E0 0C 00 08 shorted
  $0008:result:='Possible shorted';
  else result:='UNKNOW';
  end;
end;


function affenabled():Boolean;
var
  i:Integer;
begin
 Form1.btnFLASH.Caption:='Stop';
 stop:=False;
 Form1.btnFLASH.enabled:=true;
 result:=True;
 if (Form1.chkCheckRead.Checked=True) or (Form1.chkReseLt.checked=true) or (Form1.ChkAFFset.checked=true) or (Form1.chkBootNormal.checked=true) then begin
     Application.ProcessMessages;
     Sleep(500);
     Application.ProcessMessages;
     Sleep(500);
     Application.ProcessMessages;

     i:=0;
     if catchdevice<>$01 then
     begin
          repeat
                Application.ProcessMessages;
                if stop=True then i:=1000;
                if i=1000 then Break;
                Sleep(100);
                Inc(i);
                Application.ProcessMessages;
          until (catchdevice=$01) or (i=1000);
     end;

      if (i=1000) and (catchdevice<>$01) then
      begin
        if stop=true then
        begin
        form1._msg('-------AFTER FLASH BREAKED BY USER-------');
        form1._msg('');
        end;
      Application.ProcessMessages;
      Sleep(200);
      Form1.SetReady;
      Form1.TimConChk.Enabled:=true;
      Form1._msg('-> Flashing Failed! :( Maybee HW error, or Downgrade try???!');
      Form1._msg('   Anyway - try reinsert battery and PowerUp phone manualy');
      Form1._msg('');
      Form1.DisconnectFill;
      Result:=false;
      Form1.chkPPMe.Enabled:=True;
      Form1.chkMCUen.Enabled:=True;
      Form1.chkPPM1e.Enabled:=True;
      Form1.chkCNTe.Enabled:=True;
      Form1.chkAPEe.Enabled:=True;
      Form1.chkcnt3.Enabled:=True;
      end;
   Form1.TimConChk.Enabled:=true;
   Form1.btnFLASH.Caption:='FLASH';
   end;
end;

procedure starttime();
begin
 tmsstart:=0;
 tmsstart:=GetTickCount;
end;

procedure endtimecount();
begin
 tmsstop:=GetTickCount;
 tmsres:=tmsstop-tmsstart;
 fltime:=fltime+tmsres;
end;

function showtime(time:cardinal):string;
var
  sec:Integer;
begin
 sec:=0;
 sec:=(time div 1000);
 result:=FormatDateTime('hh:nn:ss',(SecondToTime(sec)));
end;

function FbusSelLoader2nd(IdR:string):boolean;
var s,s1:string;
begin
   Result:=false;
   FbusFloader:='';
   FbusSloader:='';

   if Pos(IdR,'008815B0008815C0008815C1008815D0008815D1008815D3')<>0 then
   begin
   FbusFloader:=StartDir+'Flash\UFS\nomadik8815_2nd.fg';
   FbusSloader:=StartDir+'Flash\UFS\nomadik8815_alg.fg';
   result:=true;
   exit;
   end;

   if Pos(IdR,'008815A1')<>0 then
   begin
   FbusFloader:=StartDir+'Flash\UFS\nomadik8815A1_2nd.fg';
   FbusSloader:=StartDir+'Flash\UFS\nomadik8815_A1.fg';
   result:=true;
   exit;
   end;

   if pos(IdR,'171007001710070117100702171007031710070417100708')<>0 then
   begin
   FbusFloader:=StartDir+'Flash\UFS\helen3_2nd.fg';
   if pos('OMAP1610 GBBM-1.8.1',algo)>0 then FbusSloader:=StartDir+'Flash\UFS\h3_sam_nand_gbbm.fg' else
    begin
     case flven of
     $00A100EC,$00A1002C,$00780098,$00360098,$003600EC:FbusSloader:=StartDir+'Flash\UFS\h3_sam_nand_xsr.fg' //APE ALG0 Ver 1.49.0
     else FbusSloader:=StartDir+'Flash\UFS\h3_xsr15_flash_alg.fg';
     end;
    end;
   result:=true;
   exit;
   end;
   //OMAP2420 UNISTORE-II-1.5.1 ALG // teflon_sam_nand_xsr151_m1.fg
   if pos(IdR,'24200703242007042420070524200706')<>0 then
   begin
   FbusFloader:=StartDir+'Flash\UFS\omap2420_m1_2nd.fg';
        if Pos('OMAP2420 UNISTORE-II-1.5.1',algo)<>0
        then FbusSloader:=StartDir+'Flash\UFS\teflon_sam_nand_xsr151_m1.fg'
        else
        if Pos('OMAP2420 UNISTORE-II-1.2.1',algo)<>0
        then FbusSloader:=StartDir+'Flash\UFS\teflon_sam_nand_xsr_m1.fg'
        else FbusSloader:=StartDir+'Flash\UFS\OMAP2420_XSR15_alg.fg';
   result:=true;
   exit;
   end;
   if Pos(IdR,'0003192101002000000C1921010020000003192101002100000C1921010021000003192101002200000C1921010022000003192101012200000C192101012200')<>0 then
   begin
   FbusFloader:=StartDir+'Flash\UFS\RAP3Gv2_2nd.fg';
   FbusSloader:=StartDir+'Flash\UFS\RAP3Gv3_algo.fg';
   result:=true;
   exit;
   end;
   s:='0103192101003000010C1921010030000103192101013000010C1921010130000103192101003100010C1921010031000303192101023000030C192101023000';
   s1:='0303192101033000030C1921010330000103192101001101010C1921010011010003192101001002000C1921010010020013192101001002001C192101001002';
   s:=s+s1;
   if pos(idr,s)<>0 then 
   begin
   FbusFloader:=StartDir+'Flash\UFS\RAP3Gv3_2nd.fg';
    case flicven of
    $89820089,$89810089 : FbusSloader:=StartDir+'Flash\UFS\RAP3Gv3_algo_v1331.fg';
    else FbusSloader:=StartDir+'Flash\UFS\RAP3Gv3_algo.fg';
    end;
   result:=true;
   exit;
   end;
   s:='0003192101001203000C1921010012034003192101001203400C1921010012030003192101002003000C1921010020034003192101002003400C1921010020034003192101011103400C1921010111034003192101021103400C1921010211034003192101031103400C1921010311034';
   s1:='003192101011105400C192101011105400C192101021105400C1921010311054003192101051103400C192101051103400C1921010511054003192101051105';
   s:=s+s1;
   if pos(idr,s)<>0 then 
   begin
   FbusFloader:=StartDir+'Flash\UFS\RAPIDOv11_2nd.fg';
   FbusSloader:=StartDir+'Flash\UFS\RAPIDOv11_algo.fg';
   result:=true;
   exit;
   end;
   
   if Pos (IdR,'0003192103002107000C1921030021070003192103012107000C192103012107000C1921030221070003192103022107')<>0 then begin
     FbusFloader:=StartDir+'Flash\RAPUv21_2nd.fg';
     Result:=true;
     exit;
   end;
   if Pos (IdR,'4003192102001104400C1921020011046003192102001104600C1921020011046003192102011104600C1921020111046003192102021104600C1921020211046003192102031104600C192102031104')<>0 then begin
     FbusFloader:=StartDir+'Flash\UFS\RAPUv11_2nd.fg';
     FbusSloader:=StartDir+'Flash\UFS\RAPUv11_algo_xsr16.fg';
     Result:=true;
     exit;
   end;
   s:='0203192102004000020C1921020040000203192102024000020C192102024000020C1921020041000203192102004100020C1921020141000203192102014100020C1921020140000203192102014000';
   s1:='020C19210203400002031921020340000203192102024100020C1921020241000203192102034100020C1921020341000203192102054100020C1921020541000203192102044100020C192102044100';
   s:=s+s1;
   if Pos (IdR,s)<>0 then begin
     FbusFloader:=StartDir+'Flash\UFS\RAP3Gv4_2nd.fg';
     FbusSloader:=StartDir+'Flash\UFS\RAP3Gv4_algo_xsr16.fg';
     Result:=true;
     exit;
   end;
  
end;

function LastPos(SearchStr, Str: string): Integer;
 var
    i: Integer;
   TempStr: string;
 begin
   Result := Pos(SearchStr, Str);
   if Result = 0 then Exit;
   if (Length(Str) > 0) and (Length(SearchStr) > 0) then
   begin
     for i := Length(Str) + Length(SearchStr) - 1 downto Result do
     begin
       TempStr := Copy(Str, i, Length(Str));
       if Pos(SearchStr, TempStr) > 0 then
       begin
         Result := i;
         break;
       end;
     end;
   end;
 end;

 // Search for the next occurence of a string from a certain Position
function NextPos(SearchStr, Str: string; Position: Integer): Integer;
 begin
   Delete(Str, 1, Position - 1);
   Result := Pos(SearchStr, upperCase(Str));
   if Result = 0 then Exit;
   if (Length(Str) > 0) and (Length(SearchStr) > 0) then
     Result := Result + Position + 1;
 end;

function getasic(b:byte):string;
begin
 case b of
 $00 : result:='CMT';
 $01 : result:='APE'
 else result:='UNK['+byte2str(b)+']';
 end;
end;

function getsub(b:byte):string;
begin
 case b of
 $00 : result:='NOR';
 $01 : result:='NAND';
 $03 : result:='NAND'
 else result:='UNK['+byte2str(b)+']';
 end;
end;

procedure UkeyClear();
begin
  UkeyData.hash:='';
  UkeyData.PID:='';
  UkeyData.key:='';
end;

function convertimages40(imname:string):boolean;
var
     CNT_PN_Sector        : Byte;
     res                  : Boolean;
     image                : String;
     fs                   : TFileStream;
     ms                   : TMemoryStream;
     buf                  : array[0..$3FFFF] of byte;
begin
     result:=False;
     Form1._msg('ConvertImage: Processing '+ExtractFileName(imname));
     Application.ProcessMessages;
     fs:=TFileStream.Create(imname,fmOpenRead);
     fs.Read(buf[0] ,1);
     fs.Free;

     if buf[0]<>$B2 then
     begin
          Form1._msg('ConvertImage: Image file is damaged');
          exit;
     end;

     GetPageSize(imname, CNT_PN_Sector, res);
     if Not res then
     begin
          Form1._msg('ConvertImage: Error Image file converting');
          exit;
     end;

     if pos('_128',imname)>0 then CNT_pn_sector:=128;
     
     if CNT_PN_Sector=64 then
     begin
          Form1._msg('ConvertImage: Page Size is 64K, converting...');
          Application.ProcessMessages;
          GetFlashArea(imname, {EraseArea,} res);
          if Not Res then
          begin
               Form1._msg('ConvertImage: Error Image file converting');
               Form1._msg('');
               exit;
          end;

          ms:=TMemoryStream.Create;
          Image64to128(imname, ms, res);
          if Not Res then
          begin
               Form1._msg('ConvertImage: Error Image file converting');
               Form1._msg('');
               ms.Free;
               exit;
          end;

          Form1._msg('ConvertImage: File converted');
          ms.Seek(0, sofrombeginning);
          ms.SaveToFile(imname+'_128');
          result:=True;
          ms.Free;
     end

     else

     if CNT_PN_Sector=128 then
     begin
          Form1._msg('ConvertImage: Page Size is 128K, no need convert');
          //Form1._msg('');
          Application.ProcessMessages;
     end

     else

     begin
          Form1._msg('ConvertImage: Unknow Page Size [already 128?] ');
          //Form1._msg('');
          exit;
     end;
end;

function checkcnt(imname:string):integer;
var
     buf: array[0..$3FFFF] of byte;
     HdrLen,
     HdrSeems,
     CurrSeem,
     CurrSeemLen       : Integer;
     ImagePageSize     : Word;
     i                 : Integer;
     res, NeedConvert  : Boolean;
     fs                : TFileStream;
     ms                : TMemoryStream;
     f5                : Boolean;
begin
     imname:=image;
     //Form1._msg('CheckImage: Processing '+ExtractFileName(imname));
try
     currseem:=0;
     f5:=false;
     fs:=TFileStream.Create(imname,fmOpenRead);
     fs.Read(buf[0] ,1);
     if buf[0]<>$B2 then
     begin
          Form1._msg('CheckImage: Image file is damaged');
          fs.Free;
          result:=0;
          exit;
     end;

     fs.ReadBuffer(buf[0], 4);//Длина Flash-header'a
     HdrLen   := HexToInt(IntToHex(buf[0], 2)+IntToHex(buf[1], 2)+IntToHex(buf[2], 2)+IntToHex(buf[3], 2));
     fs.Seek(4,soFromCurrent);
     HdrSeems := HdrLen+5;
     while fs.Position<HdrSeems do
     begin
       Application.ProcessMessages;
       //Form1._msg(IntToStr(fs.Position));
          fs.ReadBuffer(CurrSeem, 1);
          //Form1._msg('curr : '+byte2str(CurrSeem));
          Application.ProcessMessages;
          if (CurrSeem=$E4) or (CurrSeem=$E5) or (CurrSeem=$EA) or
             (CurrSeem=$EE) or (CurrSeem=$F3) then
          begin
               fs.ReadBuffer(buf[0], 2);
               CurrSeemLen:=(buf[0]*$100)+buf[1];
               fs.Seek(CurrSeemLen, sofromCurrent);
          end else

          begin
               fs.ReadBuffer(buf[0], 1);
               CurrSeemLen:=buf[0];
               if CurrSeemLen<1 then fs.ReadBuffer(CurrSeemLen, 1);

               //Чтение текущей разметки image-файла
               if (CurrSeem=$F5) then
               begin
                    f5:=True;
                    if CurrSeemLen<>2 then form1._msg('Unknow Image-file');
                    fs.ReadBuffer(ImagePageSize, CurrSeemLen);

                    if ImagePageSize=$1100 then
                    begin
                         NeedConvert:=false;
                         //Form1._msg('ConvertImage: Page Size is 128K, using direct mode');
                         result:=2;
                         fs.Free;
                         Exit;
                    end else
                    if ImagePageSize=$1000 then
                    begin
                         NeedConvert:=true;
                         //form1._msg('CheckImage: Page Size is 64K, using 2-stage mode');
                         result:=1;
                         fs.Free;
                         Exit;
                    end
                    else
                    begin
                     //form1._msg('ConvertImage: Unknow Page Size :( ');
                     result:=3;
                     fs.Free;
                     Exit;
                     end;
               end;
               fs.Seek(CurrSeemLen, sofromCurrent);
          end;
     end;
     fs.Free;
     if f5=false then begin
     //Form1._msg('CheckImage: cnt size not detected');
     result:=4;
     exit;
     end;
except
        on E:Exception do
        begin
             fs.Free;
             Form1._msg('CheckImage Error: '+E.Message);
             Result:=0;
        end;
    end;
end;

end.
