1- using OdinSharpLib . Pit ;
1+ using K4os . Compression . LZ4 . Streams ;
2+ using OdinSharpLib . Pit ;
23using OdinSharpLib . Port ;
34using OdinSharpLib . structs ;
45using OdinSharpLib . util ;
@@ -21,6 +22,7 @@ public class Odin
2122 public PITData PitTool = new PITData ( ) ;
2223
2324 public event LogDelegate Log ;
25+ public event ProgressChangedDelegate ProgressChanged ;
2426
2527 /// <summary>
2628 /// Finding samsung devices download mode port
@@ -191,7 +193,6 @@ public void StopOperations()
191193 }
192194
193195
194-
195196 public async Task < bool > PDAToNormal ( )
196197 {
197198 try
@@ -251,6 +252,318 @@ public async Task<Result> Write_Pit(byte[] pit)
251252
252253 return Result ;
253254 }
255+
256+ private FileFlash FoundItem ( List < FileFlash > files , TPIT_Entry partition )
257+ {
258+ foreach ( var item in files )
259+ {
260+ var filename = item . FileName ;
261+ var extension = Path . GetExtension ( item . FileName ) ;
262+ if ( ! string . IsNullOrEmpty ( extension ) && extension . ToLower ( ) == ".lz4" )
263+ {
264+ filename = filename . Substring ( 0 , filename . Length - 4 ) ;
265+ }
266+ else if ( filename . Contains ( "/" ) )
267+ {
268+ filename = filename . Substring ( filename . IndexOf ( "/" ) ) ;
269+ }
270+ if ( filename == partition . MflashFilename )
271+ {
272+ return item ;
273+ }
274+ }
275+ return null ;
276+ }
277+
278+ private FileFlash FoundItem ( FileFlash files , TPIT_Entry partition )
279+ {
280+
281+ var filename = files . FileName ;
282+ var extension = Path . GetExtension ( files . FileName ) ;
283+ if ( ! string . IsNullOrEmpty ( extension ) && extension . ToLower ( ) == ".lz4" )
284+ {
285+ filename = filename . Substring ( 0 , filename . Length - 4 ) ;
286+ }
287+ else if ( filename . Contains ( "/" ) )
288+ {
289+ filename = filename . Substring ( filename . IndexOf ( "/" ) ) ;
290+ }
291+ if ( filename == partition . MflashFilename )
292+ {
293+ return files ;
294+ }
295+ return null ;
296+ }
297+
298+ public long Calculate ( int sessionLen )
299+ {
300+ return ( sessionLen - 1L >> 17 ) + 1L << 17 ;
301+ }
302+
303+ private async Task < bool > SendAsync ( TPIT_Entry entry , Stream inputStream ,
304+ int sessionLength , bool isLast , Action < long > addProgressAction , int EfsClear = 0 , int BootUpdate = 0 )
305+ {
306+ SamsungLokeCommand command = new SamsungLokeCommand ( 102 ) ;
307+ await cmd . LOKE_SendCMD ( Device , command ) ;
308+ command = new SamsungLokeCommand ( 102 , 2 , Calculate ( sessionLength ) ) ;
309+ await cmd . LOKE_SendCMD ( Device , command ) ;
310+ int sent = 0 ;
311+ byte [ ] flashBuffer = new byte [ 1048576 ] ;
312+ byte [ ] flashResponseBuffer = new byte [ 8 ] ;
313+ while ( sent < sessionLength )
314+ {
315+ Array . Clear ( flashBuffer , 0 , flashBuffer . Length ) ;
316+ int toRead = Math . Min ( flashBuffer . Length , sessionLength - sent ) ;
317+ if ( await inputStream . ReadAsync ( flashBuffer , 0 , toRead ) != toRead )
318+ {
319+ throw new ArgumentException ( "Cannot read input stream" ) ;
320+ }
321+ await Device . WritePort ( flashBuffer , flashBuffer . Length ) ;
322+
323+ flashResponseBuffer = await Device . ReadPort ( 8 ) ;
324+ sent += toRead ;
325+ addProgressAction ( toRead ) ;
326+ }
327+ command = new SamsungLokeCommand ( 102 , 3 , entry . MbinaryType , sessionLength ) ;
328+ //await LOKE_SendCMD(command);
329+ if ( entry . MbinaryType == 1L )
330+ {
331+ SamsungLokeCommand samsungLokeCommand = command . Clone ( ) ;
332+ samsungLokeCommand . Identifier = ( isLast ? 1 : 0 ) ;
333+ samsungLokeCommand . SessionEnd = ( int ) entry . MdeviceType ;
334+ samsungLokeCommand . EfsClear = ( int ) entry . Midentifier ;
335+ command = samsungLokeCommand ;
336+ }
337+ else
338+ {
339+ SamsungLokeCommand samsungLokeCommand2 = command . Clone ( ) ;
340+ samsungLokeCommand2 . DeviceId = ( int ) entry . MdeviceType ;
341+ samsungLokeCommand2 . Identifier = ( int ) entry . Midentifier ;
342+ samsungLokeCommand2 . SessionEnd = ( isLast ? 1 : 0 ) ;
343+ command = samsungLokeCommand2 ;
344+ }
345+ command . BootUpdate = BootUpdate ;
346+ return await cmd . LOKE_SendCMD ( Device , command ) ;
347+
348+ }
349+
350+ public async Task < bool > WriteAsync ( TPIT_Entry entry , long size , Stream inputStream , int EfsClear = 0 , int BootUpdate = 0 )
351+ {
352+ int maxSessionLen = ( ( entry . MdeviceType == 1L || entry . MdeviceType == 2L || entry . MdeviceType == 8L ) ? 31457280 : 104857600 ) ;
353+ int sessionCount = ( int ) ( size / maxSessionLen ) ;
354+ if ( size % maxSessionLen != 0L )
355+ {
356+ int num = sessionCount + 1 ;
357+ sessionCount = num ;
358+ }
359+ ProgressChanged ? . Invoke ( entry . MflashFilename , size , 0L , 0 ) ;
360+ long currentProgress = 0L ;
361+ long sent = 0L ;
362+ int sessionIndex = 0 ;
363+ while ( sessionIndex < sessionCount )
364+ {
365+ int sessionLen = ( int ) Math . Min ( maxSessionLen , size - sent ) ;
366+ bool isLast = sessionIndex == sessionCount - 1 ;
367+ Action < long > addProgressAction = delegate ( long ff )
368+ {
369+ currentProgress += ff ;
370+ ProgressChanged ? . Invoke ( entry . MflashFilename , size , currentProgress , currentProgress ) ;
371+ } ;
372+ var write = await SendAsync ( entry , inputStream , sessionLen , isLast , addProgressAction , EfsClear , BootUpdate ) ;
373+ if ( ! write )
374+ {
375+ return false ;
376+ }
377+ sent += sessionLen ;
378+ int num = sessionIndex + 1 ;
379+ sessionIndex = num ;
380+ }
381+ return true ;
382+ }
383+
384+ private async Task < bool > FlashFromTar ( string TarFile , long size ,
385+ string inp_filename ,
386+ TPIT_Entry pit ,
387+ int EFSClear ,
388+ int BootUpdate )
389+ {
390+
391+ var TarFileData = new cListFileData ( ) ;
392+ var temp1 = tar . TarInformation ( TarFile ) ;
393+ foreach ( var item in temp1 )
394+ {
395+ if ( inp_filename == item . Filename )
396+ {
397+ TarFileData = item ;
398+ break ;
399+ }
400+ }
401+
402+ string extension = Path . GetExtension ( inp_filename ) ;
403+ using ( var reader = new BinaryReader ( File . Open ( TarFile , FileMode . Open ) ) )
404+ {
405+ var j = TarFileData . FilePosStart ;
406+ reader . BaseStream . Position = j ;
407+ if ( extension == ".lz4" )
408+ {
409+ using ( var lz4 = LZ4Stream . Decode ( reader . BaseStream ) )
410+ {
411+ await WriteAsync ( pit , size , lz4 , EFSClear , BootUpdate ) ;
412+ }
413+ }
414+ else
415+ {
416+ await WriteAsync ( pit , size , reader . BaseStream , EFSClear , BootUpdate ) ;
417+ }
418+
419+ return true ;
420+ }
421+ }
422+
423+ public List < FileFlash > CurreptedPartitions ( List < FileFlash > ready , List < FileFlash > Writed )
424+ {
425+ var ListCurrepted = new List < FileFlash > ( ) ;
426+ foreach ( var item in ready )
427+ {
428+ if ( ! item . Enable )
429+ {
430+ continue ;
431+ }
432+ var exst = false ;
433+ foreach ( var writen in Writed )
434+ {
435+ if ( item . FileName == writen . FileName )
436+ {
437+ exst = true ;
438+ }
439+ }
440+ if ( ! exst )
441+ {
442+ ListCurrepted . Add ( item ) ;
443+ }
444+ }
445+ return ListCurrepted ;
446+ }
447+
448+ public async Task < bool > FlashFirmware ( List < FileFlash > list , List < TPIT_Entry > pit , int EfsClear , int BootUpdate , bool Debug )
449+ {
450+ var WritenItem = new List < FileFlash > ( ) ;
451+ foreach ( var item in pit )
452+ {
453+ var FileItem = FoundItem ( list , item ) ;
454+ if ( FileItem != null )
455+ {
456+ if ( ! FileItem . Enable )
457+ {
458+ continue ;
459+ }
460+ if ( Debug )
461+ {
462+ Log ? . Invoke ( $ "Flashing { FileItem . FileName } : ", MsgType . Message ) ;
463+ }
464+ if ( ! await FlashFromTar ( FileItem . FilePath , FileItem . RawSize , FileItem . FileName ,
465+ item , EfsClear , BootUpdate ) )
466+ {
467+ if ( Debug )
468+ {
469+ Log ? . Invoke ( $ " : Failed", MsgType . Result ) ;
470+ }
471+ return false ;
472+ }
473+ else
474+ {
475+ WritenItem . Add ( FileItem ) ;
476+ if ( Debug )
477+ {
478+ Log ? . Invoke ( $ " : Ok", MsgType . Result ) ;
479+ }
480+ }
481+
482+ }
483+ }
484+
485+ var GetCurrepted = CurreptedPartitions ( list , WritenItem ) ;
486+ if ( GetCurrepted . Count > 0 )
487+ {
488+ Log ? . Invoke ( "File partition cannot find in your device partition : " , MsgType . Message ) ;
489+ foreach ( var currepted in GetCurrepted )
490+ {
491+ Log ? . Invoke ( currepted . FileName , MsgType . Result ) ;
492+ }
493+ }
494+
495+ return true ;
496+ }
497+
498+
499+ private async Task < bool > FlashSingle ( string Filepath , string inp_filename , TPIT_Entry pit ,
500+ int EFSClear ,
501+ int BootUpdate )
502+ {
503+
504+ string extension = Path . GetExtension ( inp_filename ) ;
505+ ProgressChanged ? . Invoke ( inp_filename , 0 , 0 , 0 ) ;
506+ using ( var reader = new BinaryReader ( File . Open ( Filepath , FileMode . Open ) ) )
507+ {
508+ var j = 0L ;
509+ if ( extension == ".lz4" )
510+ {
511+ reader . BaseStream . Position = j ;
512+ using ( var lz4 = LZ4Stream . Decode ( reader . BaseStream ) )
513+ {
514+ await WriteAsync ( pit , lz4 . Length , lz4 , EFSClear , BootUpdate ) ;
515+ }
516+ }
517+ else
518+ {
519+ await WriteAsync ( pit , reader . BaseStream . Length , reader . BaseStream , EFSClear , BootUpdate ) ;
520+ }
521+
522+ return true ;
523+ }
524+ }
525+
526+ public async Task < bool > FlashSingleFile ( FileFlash flash , List < TPIT_Entry > pit , int EfsClear , int BootUpdate , bool Debug )
527+ {
528+ var WritenItem = new FileFlash ( ) ;
529+
530+ foreach ( var item in pit )
531+ {
532+ var FileItem = FoundItem ( flash , item ) ;
533+ if ( FileItem != null )
534+ {
535+ if ( Debug )
536+ {
537+ Log ? . Invoke ( $ "Flashing { FileItem . FileName } : ", MsgType . Message ) ;
538+ }
539+
540+ if ( ! await FlashSingle ( FileItem . FilePath , FileItem . FileName ,
541+ item , EfsClear , BootUpdate ) )
542+ {
543+ if ( Debug )
544+ {
545+ Log ? . Invoke ( "Failed" , MsgType . Result ) ;
546+ }
547+ return false ;
548+ }
549+ else
550+ {
551+ WritenItem = FileItem ;
552+ if ( Debug )
553+ {
554+ Log ? . Invoke ( "Ok" , MsgType . Result ) ;
555+ }
556+ return true ;
557+ }
558+ }
559+ }
560+ if ( string . IsNullOrEmpty ( WritenItem . FileName ) )
561+ {
562+ Log ? . Invoke ( "File Not Found In Device Partition : " , MsgType . Message ) ;
563+ Log ? . Invoke ( WritenItem . FileName , MsgType . Result ) ;
564+ }
565+ return true ;
566+ }
254567
255568 public async Task < Result > Write_Pit ( string File )
256569 {
0 commit comments