SevenZipVCL.pas
上传用户:ctlcnc
上传日期:2021-12-10
资源大小:4933k
文件大小:104k
源码类别:

2D图形编程

开发平台:

Delphi

  1. unit SevenZipVCL;
  2. (*
  3.    This Unit is under Mozilla Public Licence
  4.     (
  5.      - You can use this Unit for free in free, share and commercial application.
  6.      - Mark clearly in your Readme or Help file that you use this unit/VCL with a link the
  7.        SevenZipVCL Homepage ( http://www.rg-software.de )
  8.      - Any changes of the source must be publised ( Just send it to me :- ) SevenZipVCL@rg-software.de )
  9.     )
  10.    TsevenZip by Ivo Andonov
  11.    TSevenZipVCL by Rainer Geigenberger ( -> http://www.rg-software.de - SevenZipVCL@rg-software.de )
  12.    Thanks to:
  13.     - Marko Kamin
  14.     - Craig Peterson
  15.     - Roberto
  16.     - Erik Smith
  17.     - Sergey Prokhorov
  18.    Dll Usage:
  19.         For develpoment put the dll into the Windows directory
  20.         Running the Application stand alone you can put the dll into the Application directory
  21.  History:
  22.    Version 0.1
  23.     - Start
  24.    Version 0.2
  25.     - Changed everything to Widestring
  26.     - Added WideStringList_
  27.     - Added TWideStringArray
  28.     - Adding RelativePath works
  29.     - Adding works with Recursive Directory
  30.     - Adding with Wildcards ( only *.txt or something )
  31.     - Progress for files ( With SetCompleted VCL interaction works )
  32.    Version 0.3
  33.     - Added time reading and writing
  34.    Version 0.4
  35.     - Added Extract
  36.     - Added Test via Extract( True )
  37.     - Set Filetime during extraction
  38.     - Progress during extraction works ( small files will not be displayed alone )
  39.    Version 0.5
  40.     - Changes here and there
  41.     - Clean up code
  42.    Version 0.6
  43.     - Changed "Extract all files"
  44.     - Fixed bug in handling directories during extract
  45.     - Attribute to extracted files works now
  46.     - Fixed LastwriteTime during adding
  47.     - Changed some functions
  48.    Version 0.6.1
  49.     - Some minor changes
  50.     - Fixed some bugs
  51.     - Added MaxProgrees to selected files
  52.     - Added some missing GUID - not used now :- )
  53.    Version 0.6.2
  54.     - Compression strength could be set
  55.     - Drive letter to Storepath option included
  56.     - Changes made by Marko Kamin
  57.    Version 0.6.3
  58.     - Changed Archive options to new type Addopts
  59.     - Solid settings works now
  60.    Version 0.6.4
  61.     - Implemented SFX creation
  62.    Version 0.6.4b
  63.     - LZMAStrength added
  64.    Version 0.6.5
  65.     - PPMD method added
  66.    Version 0.6.5a
  67.     - Fixed bug during listing of 0 byte files
  68.    
  69.    Version 0.6.5b
  70.     - Fixed bug during creating files for extract/SFXarchive in Tstreamwriter
  71.    Version 0.6.5c
  72.     - Fixed bug Creating SFX
  73.    Version 0.6.6
  74.     - Adding and extracting can be canceled
  75.    Version 0.6.6a
  76.     - Adding Extract without path
  77.    Version 0.6.6c
  78.     - Reading SFX
  79.     - Number of files
  80.     - New: IsSFX and SXFOffset
  81.     - New: Function ConvertSFXto7z
  82.     - New: Function Convert7ztoSFX
  83.    Version 0.6.7
  84.     - Added some Widestring function form TNTWare TNT Controls http://www.tntware.com/
  85.     - New: OnExtractOverwrite - Do not work with Messageboxes right now
  86.     - Include Extractoverwrite in Extractoption
  87.    Version 0.6.7a
  88.     - Changed constructor and destructor to avoid excaption - Thanks to Roberto jjw
  89.     - Fixed Unicode bug during adding
  90.    Version 0.6.7b
  91.     - Clean up code. Thanks to Erik Smith
  92.     - Rewrote Add function. Thanks to Erik Smith
  93.    Version 0.6.7c
  94.    - Multivolume support added - Thanks to Sergey Prokhorov
  95.    - Begin password support - Thanks to Sergey Prokhorov
  96.    Version 0.6.7e
  97.    - Multivolume support improved
  98.    - Clean up code
  99.    Version 0.6.8a
  100.    - Password implemented
  101.    Version 0.6.8e
  102.    - Implementation of 9x support started
  103.    - Cleanup some comments
  104.    Version 0.7.0
  105.    - OpenarchiveCallback implemented
  106.    - Encrypt filename option implemented
  107.    Version 0.7.1
  108.    - Fixed Bug in password support
  109.    Version 0.7.1 -> modified by Lifepower (lifepower@mail333.com)
  110.    - Very minor modifications to prevent unnecessary warnings
  111. *)
  112. (*
  113.    Known Issues / Things ToDo:
  114.    
  115.     - No archive properties during listing
  116.     - With Solid archives filenames and progress during extract comes very late ( at the end )
  117.     - No deleting files from archive
  118.   Please mark all changes with your sign and date e.g. rg 01.01.06
  119.   and send it to me SevenZipVCL@rg-software.de
  120. *)
  121. // Use normal dll version
  122. {$DEFINE Use7zdll}
  123. // Lifepower (07-Jan-2007):
  124. //  Disabled warnings W1002 and W1005 for platform-specific stuff.
  125. {$WARN UNIT_PLATFORM OFF}
  126. {$WARN SYMBOL_PLATFORM OFF}
  127. // Use Resfile with 7z.dll, no external dll, accessing through BTMemoryModule
  128. //{$DEFINE UseRes7zdll}
  129. interface
  130. {$IFDEF UseRes7zdll}
  131.   {$R 7za.res}
  132. {$ENDIF}
  133. uses
  134.   Windows, SysUtils, Classes, ActiveX,comobj,filectrl
  135.   {$IFDEF UseRes7zdll}
  136.   ,BTMemoryModule
  137.   {$ENDIF}
  138.   ;
  139. const
  140. //7z internal consts
  141. //Extract
  142.   //NAskMode
  143.   kExtract = 0;
  144.   kTest    = 1;
  145.   kSkip    = 2;
  146.   //NOperationResult
  147.   kOK                = 0;
  148.   kUnSupportedMethod = 1;
  149.   kDataError         = 2;
  150.   kCRCError          = 3;
  151.   FNAME_MAX32 = 512;
  152. // SevenZIP onMessage Errorcode
  153.   FNoError           = 0;
  154.   FFileNotFound      = 1;
  155.   FDataError         = 2;
  156.   FCRCError          = 3;
  157.   FUnsupportedMethod = 4;
  158.   FJustAnError       = 5;
  159.   FUsercancel        = 6;
  160.   FNoSFXarchive      = 7;
  161.   FSFXModuleError    = 8;
  162. const
  163.   kpidNoProperty = 0;
  164.   kpidHandlerItemIndex = 2;
  165.   kpidPath = 3;
  166.   kpidName = 4;
  167.   kpidExtension = 5;
  168.   kpidIsFolder = 6;
  169.   kpidSize = 7;
  170.   kpidPackedSize = 8;
  171.   kpidAttributes = 9;
  172.   kpidCreationTime = 10;
  173.   kpidLastAccessTime = 11;
  174.   kpidLastWriteTime = 12;
  175.   kpidSolid = 13;
  176.   kpidCommented = 14;
  177.   kpidEncrypted = 15;
  178.   kpidSplitBefore = 16;
  179.   kpidSplitAfter = 17;
  180.   kpidDictionarySize = 18;
  181.   kpidCRC = 19;
  182.   kpidType = 20;
  183.   kpidIsAnti = 21;
  184.   kpidMethod = 22;
  185.   kpidHostOS = 23;
  186.   kpidFileSystem = 24;
  187.   kpidUser = 25;
  188.   kpidGroup = 26;
  189.   kpidBlock = 27;
  190.   kpidComment = 28;
  191.   kpidPosition = 29;
  192.   kpidTotalSize = $1100;
  193.   kpidFreeSpace = $1101;
  194.   kpidClusterSize = $1102;
  195.   kpidVolumeName = $1103;
  196.   kpidLocalName = $1200;
  197.   kpidProvider = $1201;
  198.   kpidUserDefined = $10000;
  199. //jjw 18.10.2006
  200. type
  201.   TCreateObjectFunc = function ( const clsid: PGUID; const iid: PGUID; out _out ): Integer; stdcall;
  202. //----------------------------------------------------------------------------------------------------
  203. //--------------Widestring Classes--------------------------------------------------------------------
  204. //----------------------------------------------------------------------------------------------------
  205. type
  206.   TWideStringArray = array of WideString;
  207.   TWideStringList_ = class( TObject )
  208.    private
  209.    public
  210.     WStrings: array of WideString;
  211.     Count: Longword;
  212.     constructor Create;
  213.     procedure Clear;
  214.     procedure AddString( s: WideString );
  215.     procedure RemoveString( s: WideString );
  216.    end;
  217. type
  218.   TCompressType = ( LZMA,PPMD );
  219.   TCompressStrength = ( SAVE,FAST,NORMAL,MAXIMUM,ULTRA );
  220.   TLZMAStrength = 0..27;
  221.   TPPMDMem = 1..31;
  222.   TPPMDSize = 2..32;
  223.   AddOptsEnum = ( AddRecurseDirs, AddSolid, AddStoreOnlyFilename, AddIncludeDriveLetter, AddEncryptFilename );
  224.   AddOpts = Set Of AddOptsEnum;
  225.   ExtractOptsEnum = ( ExtractNoPath,ExtractOverwrite );
  226.   ExtractOpts = Set Of ExtractOptsEnum;
  227. //----------------------------------------------------------------------------------------------------
  228. //----------------------------------------------------------------------------------------------------
  229. //--------------Start SevenZip Interface-------------------------------------------------------
  230. //----------------------------------------------------------------------------------------------------
  231. //----------------------------------------------------------------------------------------------------
  232. type
  233.   TInterfacedObject = class( TObject, IUnknown )
  234.   protected
  235.     FRefCount: Integer;
  236.     function QueryInterface( const IID: TGUID; out Obj ): HResult; stdcall;
  237.     function _AddRef: Integer; stdcall;
  238.     function _Release: Integer; stdcall;
  239.   public
  240.     procedure AfterConstruction; override;
  241.     procedure BeforeDestruction; override;
  242.     class function NewInstance: TObject; override;
  243.     property RefCount: Integer read FRefCount;
  244.   end;
  245. const
  246. //  Correct below for 7-Zip 4.23 or 4.29. Comment this line
  247.   {$DEFINE 7z423_}
  248.   {$DEFINE 7z429}
  249.   {$IFDEF 7z423}
  250.   szCLSID_CFormat7z = '{23170F69-40C1-278A-1000-000110050000}';
  251.   szIID_IInArchive = '{23170F69-40C1-278A-0000-000100080000}';
  252.   szIID_IOutArchive = '{23170F69-40C1-278A-0000-000100020000}';
  253.   szIID_ISetProperties = '{23170F69-40C1-278A-0000-000100030000}';
  254.   szIID_IOutStream = '{23170F69-40C1-278A-0000-000000040000}';
  255.   szIID_ISequentialInStream = '{23170F69-40C1-278A-0000-000000010000}';
  256.   szIID_IInStream = '{23170F69-40C1-278A-0000-000000030000}';
  257.   szIID_IStreamGetSize = '{23170F69-40C1-278A-0000-000000060000}';
  258.   szIID_IArchiveOpenCallback = '{23170F69-40C1-278A-0000-000100010000}';
  259.   szIID_IArchiveExtractCallback = '{23170F69-40C1-278A-0000-000100090000}';
  260.   szIID_IArchiveUpdateCallback = '{23170F69-40C1-278A-0000-000100040000}';
  261.   szIID_IProgress = '{23170F69-40C1-278A-0000-000000050000}';
  262.   szIID_ISequentialOutStream = '{23170F69-40C1-278A-0000-000000020000}';
  263.   {$ENDIF}
  264.   {$IFDEF 7z429}
  265. //000
  266.   szIID_IProgress =                         '{23170F69-40C1-278A-0000-000000050000}';
  267. //30
  268.   szIID_ISequentialInStream =               '{23170F69-40C1-278A-0000-000300010000}';
  269.   szIID_ISequentialOutStream =              '{23170F69-40C1-278A-0000-000300020000}';
  270.   szIID_IInStream =                         '{23170F69-40C1-278A-0000-000300030000}';
  271.   szIID_IOutStream =                        '{23170F69-40C1-278A-0000-000300040000}';
  272.   szIID_IStreamGetSize =                    '{23170F69-40C1-278A-0000-000300060000}';
  273.   szIID_IOutStreamFlush =                   '{23170F69-40C1-278A-0000-000300070000}';
  274. //400
  275.   szIID_ICompressProgressInfo =             '{23170F69-40C1-278A-0000-000400040000}';
  276.   szIID_ICompressCoder =                    '{23170F69-40C1-278A-0000-000400050000}';
  277.   szIID_ICompressCoder2 =                   '{23170F69-40C1-278A-0000-000400180000}';
  278.   szIID_ICompressSetCoderProperties =       '{23170F69-40C1-278A-0000-000400200000}';
  279.   szIID_ICompressSetDecoderProperties =     '{23170F69-40C1-278A-0000-000400210000}';
  280.   szIID_ICompressSetDecoderProperties2 =    '{23170F69-40C1-278A-0000-000400220000}';
  281.   szIID_ICompressWriteCoderProperties =     '{23170F69-40C1-278A-0000-000400230000}';
  282.   szIID_ICompressGetInStreamProcessedSize = '{23170F69-40C1-278A-0000-000400240000}';
  283.   szIID_ICompressGetSubStreamSize =         '{23170F69-40C1-278A-0000-000400300000}';
  284.   szIID_ICompressSetInStream =              '{23170F69-40C1-278A-0000-000400310000}';
  285.   szIID_ICompressSetOutStream =             '{23170F69-40C1-278A-0000-000400320000}';
  286.   szIID_ICompressSetInStreamSize =          '{23170F69-40C1-278A-0000-000400330000}';
  287.   szIID_ICompressSetOutStreamSize =         '{23170F69-40C1-278A-0000-000400340000}';
  288.   szIID_ICompressFilter =                   '{23170F69-40C1-278A-0000-000400400000}';
  289.   szIID_ICryptoProperties =                 '{23170F69-40C1-278A-0000-000400800000}';
  290.   szIID_ICryptoSetPassword =                '{23170F69-40C1-278A-0000-000400900000}';
  291.   szIID_ICryptoSetCRC =                     '{23170F69-40C1-278A-0000-000400A00000}';
  292. //500
  293.   szIID_ICryptoGetTextPassword =            '{23170F69-40C1-278A-0000-000500100000}';
  294.   szIID_ICryptoGetTextPassword2 =           '{23170F69-40C1-278A-0000-000500110000}';
  295. //600
  296.   szIID_ISetProperties =                    '{23170F69-40C1-278A-0000-000600030000}';
  297.   szIID_IArchiveOpenCallback =              '{23170F69-40C1-278A-0000-000600100000}';
  298.   szIID_IArchiveExtractCallback =           '{23170F69-40C1-278A-0000-000600200000}';
  299.   szIID_IArchiveOpenVolumeCallback =        '{23170F69-40C1-278A-0000-000600300000}';
  300.   szIID_IInArchiveGetStream =               '{23170F69-40C1-278A-0000-000600400000}';
  301.   szIID_IArchiveOpenSetSubArchiveName =     '{23170F69-40C1-278A-0000-000600500000}';
  302.   szIID_IInArchive =                        '{23170F69-40C1-278A-0000-000600600000}';
  303.   szIID_IArchiveUpdateCallback =            '{23170F69-40C1-278A-0000-000600800000}';
  304.   szIID_IArchiveUpdateCallback2 =           '{23170F69-40C1-278A-0000-000600820000}';
  305.   szIID_IOutArchive =                       '{23170F69-40C1-278A-0000-000600A00000}';
  306.   szCLSID_CFormat7z =                       '{23170F69-40C1-278A-1000-000110070000}';
  307.   szIID_CCrypto_Hash_SHA256                = '{23170F69-40C1-278B-0703-000000000000}';
  308.   szIID_CCrypto7zAESEncoder                = '{23170F69-40C1-278B-06F1-070100000100}';
  309.   szIID_CCrypto7zAESDecoder                = '{23170F69-40C1-278B-06F1-070100000000}';
  310.   {$ENDIF}
  311.   CLSID_CFormat7z: TGUID = szCLSID_CFormat7z;
  312.   IID_IInArchive: TGUID = szIID_IInArchive;
  313.   IID_IOutArchive: TGUID = szIID_IOutArchive;
  314.   IID_ISetProperties: TGUID = szIID_ISetProperties;
  315.   IID_ICompressCoder: TGUID = szIID_ICompressCoder;
  316.   IID_ICryptoGetTextPassword: TGUID = szIID_ICryptoGetTextPassword;
  317.   IID_ICryptoGetTextPassword2: TGUID = szIID_ICryptoGetTextPassword2;
  318.   IID_ICryptoSetPassword: TGUID = szIID_ICryptoSetPassword;
  319.   IID_IOutStream: TGUID = szIID_IOutStream;
  320.   IID_ISequentialInStream: TGUID = szIID_ISequentialInStream;
  321.   IID_IInStream: TGUID = szIID_IInStream;
  322.   IID_IStreamGetSize: TGUID = szIID_IStreamGetSize;
  323.   IID_IArchiveOpenCallback: TGUID = szIID_IArchiveOpenCallback;
  324.   IID_ICompressGetSubStreamSize: TGUID = szIID_ICompressGetSubStreamSize;
  325.   IID_IArchiveOpenSetSubArchiveName: TGUID = szIID_IArchiveOpenSetSubArchiveName;
  326.   IID_IArchiveExtractCallback: TGUID = szIID_IArchiveExtractCallback;
  327.   IID_IArchiveOpenVolumeCallback: TGUID = szIID_IArchiveOpenVolumeCallback;
  328.   IID_IArchiveUpdateCallback: TGUID = szIID_IArchiveUpdateCallback;
  329.   IID_IArchiveUpdateCallback2: TGUID = szIID_IArchiveUpdateCallback2;
  330.   IID_IProgress: TGUID = szIID_IProgress;
  331.   IID_ISequentialOutStream: TGUID = szIID_ISequentialOutStream;
  332.   IID_CCrypto7zAESEncoder: TGUID = szIID_CCrypto7zAESEncoder;
  333. type
  334.   HARC = THandle;
  335.   INDIVIDUALINFO = record
  336.     dwOriginalSize: DWORD;
  337.     dwCompressedSize: DWORD;
  338.     dwCRC: DWORD;
  339.     uFlag: UINT;
  340.     uOSType: UINT;
  341.     wRatio: WORD;
  342.     wDate: WORD;
  343.     wTime: WORD;
  344.     szFileName: array [ 0..FNAME_MAX32 + 1 - 1 ] of Char;
  345.     dummy1: array [ 0..3 - 1 ] of Char;
  346.     szAttribute: array [ 0..8 - 1 ] of Char;
  347.     szMode: array [ 0..8 - 1 ] of Char;
  348.   end;
  349.   EXTRACTINGINFO = record
  350.     dwFileSize: DWORD;
  351.     dwWriteSize: DWORD;
  352.     szSourceFileName: array [ 0..FNAME_MAX32 + 1 - 1 ] of Char;
  353.     dummy1: array [ 0..3 - 1 ] of Char;
  354.     szDestFileName: array [ 0..FNAME_MAX32 + 1 - 1 ] of Char;
  355.     dummy: array [ 0..3 - 1 ] of Char;
  356.   end;
  357.   PEXTRACTINGINFOEX = ^EXTRACTINGINFOEX;
  358.   EXTRACTINGINFOEX = record
  359.     exinfo: EXTRACTINGINFO;
  360.     dwCompressedSize: DWORD;
  361.     dwCRC: DWORD;
  362.     uOSType: UINT;
  363.     wRatio: WORD;
  364.     wDate: WORD;
  365.     wTime: WORD;
  366.     szAttribute: array [ 0..8 - 1 ] of Char;
  367.     szMode: array [ 0..8 - 1 ] of Char;
  368.   end;
  369. type
  370.   ISetProperties = interface( IUnknown )
  371.     [ szIID_ISetProperties ]
  372.     function SetProperties( const names: PWideChar; const values: PPROPVARIANT; numProperties: Integer ): Integer; stdcall;
  373.   end;
  374.   ICompressProgressInfo = interface( IUnknown )
  375.     [ szIID_ICompressProgressInfo ]
  376.     function SetRatioInfo( const inSize, outSize: Int64 ): Integer; stdcall;
  377.   end;
  378.   ISequentialOutStream = interface( IUnknown )
  379.     [ szIID_ISequentialOutStream ]
  380.     function Write( const data; size: DWORD; processedSize: PDWORD ): Integer; stdcall;
  381.     {$IFDEF 7z423}
  382.     function WritePart( const data; size: DWORD; processedSize: PDWORD ): Integer; stdcall;
  383.     {$ENDIF}
  384.   end;
  385.   ISequentialInStream = interface( IUnknown )
  386.     [ szIID_ISequentialInStream ]
  387.     function Read( var data; size: DWORD; processedSize: PDWORD ): Integer; stdcall;
  388.     {$IFDEF 7z423}
  389.     function ReadPart( var data; size: DWORD; processedSize: PDWORD ): Integer; stdcall;
  390.     {$ENDIF}
  391.   end;
  392.   ICryptoGetTextPassword = interface( IUnknown )
  393.     [ szIID_ICryptoGetTextPassword ]
  394.     function CryptoGetTextPassword( var Password: PWideChar ): Integer; stdcall;
  395.   end;
  396.   ICryptoGetTextPassword2 = interface( IUnknown )
  397.     [ szIID_ICryptoGetTextPassword2 ]
  398.     function CryptoGetTextPassword2( passwordIsDefined: PInteger; var Password: PWideChar ): Integer; stdcall;
  399.   end;
  400.   ICryptoProperties = interface( IUnknown )
  401.     [ szIID_ICryptoProperties ]
  402.     function SetKey( const Data; Size: DWORD ): Integer; stdcall;
  403.     function SetInitVector( const Data; Size: DWORD ): Integer; stdcall;
  404.   end;
  405.   ICompressCoder = interface( IUnknown )
  406.     [ szIID_ICompressCoder ]
  407.     function Code( inStream: ISequentialInStream; outStream: ISequentialOutStream;
  408.       const inSize, outSize: Int64; Progress: ICompressProgressInfo ): Integer; stdcall;
  409.   end;
  410.   ICryptoSetPassword = interface( IUnknown )
  411.     [ szIID_ICryptoSetPassword ]
  412.     function CryptoSetPassword( const Data; Size: DWORD ): Integer; stdcall;
  413.   end;
  414.   ICryptoSetCRC = interface( IUnknown )
  415.     [ szIID_ICryptoSetCRC ]
  416.     function CryptoSetCRC( CRC: DWORD ): Integer; stdcall;
  417.   end;
  418.   IInStream = interface( ISequentialInStream )
  419.     [ szIID_IInStream ]
  420.     function Seek( offset: Int64; seekOrigin: DWORD;newPosition: PInt64 ): Integer; stdcall;
  421.   end;
  422.   IStreamGetSize = interface( IUnknown )
  423.     [ szIID_IStreamGetSize ]
  424.     function GetSize( var size: Int64 ): Integer; stdcall;
  425.   end;
  426.   IArchiveOpenCallback = interface( IUnknown )
  427.     [ szIID_IArchiveOpenCallback ]
  428.     function SetTotal( const files: Int64; const bytes: Int64 ): Integer; stdcall;
  429.     function SetCompleted( const files: Int64; const bytes: Int64 ): Integer; stdcall;
  430.   end;
  431.   IArchiveOpenVolumeCallback = interface( IUnknown )
  432.     [ szIID_IArchiveOpenVolumeCallback ]
  433.     function GetProperty( propID: PROPID; var value: PROPVARIANT ): Integer; stdcall;
  434.     function GetStream( const name:Widechar; var inStream: IInStream ): Integer; stdcall;
  435.   end;
  436.   IArchiveOpenSetSubArchiveName = interface( IUnknown )
  437.     [ szIID_IArchiveOpenSetSubArchiveName ]
  438.     function SetSubArchiveName( const Name: PWideString ): Integer; stdcall;
  439.   end;
  440.   IProgress = interface( IUnknown )
  441.     [ szIID_IProgress ]
  442.     function SetTotal( total: Int64 ): Integer; stdcall;
  443.     function SetCompleted( const completeValue: PInt64 ): Integer; stdcall;
  444.   end;
  445.   IArchiveExtractCallback = interface( IProgress )
  446.     [ szIID_IArchiveExtractCallback ]
  447.     function GetStream( index: DWORD; out outStream: ISequentialOutStream;  askExtractMode: DWORD ): Integer; stdcall;
  448.     // GetStream OUT: S_OK - OK, S_FALSE - skeep this file
  449.     function PrepareOperation( askExtractMode: Integer ): Integer; stdcall;
  450.     function SetOperationResult( resultEOperationResult: Integer ): Integer; stdcall;
  451.   end;
  452.   IInArchive = interface( IUnknown )
  453.     [ szIID_IInArchive ]
  454.     function Open( stream: IInStream; const maxCheckStartPosition: PInt64; openArchiveCallback: IArchiveOpenCallback ): Integer; stdcall;
  455.     function Close( ): Integer; stdcall;
  456.     function GetNumberOfItems( out numItems: DWORD ): Integer; stdcall;
  457.     function GetProperty( index: DWORD; propID: PROPID; var value: PROPVARIANT ): Integer; stdcall;
  458.     function Extract( const indices: PDWORD; numItems: DWORD;   testMode: Integer; extractCallback: IArchiveExtractCallback ): Integer; stdcall;
  459.     function GetArchiveProperty( propID: PROPID; value: PPROPVARIANT ): Integer; stdcall;
  460.     function GetNumberOfProperties( var numProperties: DWORD ): Integer; stdcall;
  461.     function GetPropertyInfo( index: DWORD; var name: TBSTR; var propID: PROPID; var varType: {PVARTYPE}Integer ): Integer; stdcall;
  462.     function GetNumberOfArchiveProperties( var numProperties ): Integer; stdcall;
  463.     function GetArchivePropertyInfo( index: DWORD; name: PBSTR; propID: PPROPID; varType: {PVARTYPE}PInteger ): Integer; stdcall;
  464.   end;
  465.   IArchiveUpdateCallback = interface( IProgress )
  466.     [ szIID_IArchiveUpdateCallback ]
  467.     //function EnumProperties( var enumerator: IEnumSTATPROPSTG ): Integer; stdcall;
  468.     function GetUpdateItemInfo( index: DWORD;
  469.       newData: PInteger; // 1 - new data, 0 - old data
  470.       newProperties: PInteger; // 1 - new properties, 0 - old properties
  471.       indexInArchive: PDWORD // -1 if there is no in archive, or if doesn't matter
  472.       ): Integer; stdcall;
  473.     function GetProperty( index: DWORD; propID: PROPID; value: PPROPVARIANT ): Integer; stdcall;
  474.     function GetStream( index: DWORD; var inStream: ISequentialInStream ): Integer; stdcall;
  475.     function SetOperationResult( operationResult: Integer ): Integer; stdcall;
  476.   end;
  477.   IArchiveUpdateCallback2 = interface( IProgress )
  478.     [ szIID_IArchiveUpdateCallback2 ]
  479.     //function EnumProperties( var enumerator: IEnumSTATPROPSTG ): Integer; stdcall;
  480.     function GetVolumeSize( index: DWORD; Size:DWord ): Integer; stdcall;
  481.     function GetVolumeStream( index: DWORD; var volumeStream: ISequentialInStream ): Integer; stdcall;
  482.   end;
  483.   IOutArchive = interface( IUnknown )
  484.     [ szIID_IOutArchive ]
  485.     function UpdateItems( outStream: ISequentialOutStream; numItems: DWORD; updateCallback: IArchiveUpdateCallback ): Integer; stdcall;
  486.     function GetFileTimeType( var _type: DWORD ): Integer; stdcall;
  487.   end;
  488.   IOutStream = interface( ISequentialOutStream )
  489.     [ szIID_IOutStream ]
  490.     function Seek( offset: Int64; seekOrigin: DWORD; newPosition: PInt64 ): Integer; stdcall;
  491.     function SetSize( newSize: Int64 ): Integer; stdcall;
  492.   end;
  493. // -----------------------------------------------------------------------------
  494.   TSevenZip = class;   // for reference only, implementated later below
  495.   TOpenVolume = procedure( var arcFileName: WideString; Removable: Boolean; out Cancel: Boolean ) of object;
  496.   TFiles = record
  497.     Name: WideString;
  498.     Handle: Integer;
  499.     Size: DWORD;
  500.     OnRemovableDrive: Boolean;
  501.   end;
  502.   TMyStreamWriter = class( TInterfacedObject, ISequentialOutStream, IOutStream )
  503.   private
  504.     arcName: WideString;
  505.     arcDate: Tdatetime;
  506.     arcAttr: DWORD;
  507.     arcCreateSFX: Boolean;
  508.     arcVolumeSize: DWORD;
  509.     arcPosition, arcSize: DWORD;
  510.     Files: array of TFiles;
  511.     function CreateNewFile: Boolean;
  512.   public
  513.     destructor Destroy; override;
  514.     constructor Create( sz: Widestring; szDate: Tdatetime; FAttr: Cardinal; VolumeSize: Integer = 0; CreateSFX: Boolean = FALSE );
  515.     function Write( const Data; Size: DWORD; ProcessedSize: PDWORD ): Integer; stdcall;
  516.     function WritePart( const Data; Size: DWORD; ProcessedSize: PDWORD ): Integer; stdcall;
  517.     function Seek( Offset: Int64; SeekOrigin: DWORD; NewPosition: PInt64 ): Integer; stdcall;
  518.     function SetSize( newSize: Int64 ): Integer; stdcall;
  519.   end;
  520.   TMyStreamReader = class( TInterfacedObject, IInStream, IStreamGetSize, ISequentialInStream )
  521.     FSevenZip: TSevenZip;
  522.     arcName: WideString;
  523.     arcPosition, arcSize: DWORD;
  524.     Files: array of TFiles;
  525.     FOnOpenVolume: TOpenVolume;
  526.     FArchive: Boolean;
  527.     FMultivolume: Boolean;
  528.     function BrowseForFile( Title: PWideChar; var Name: WideString ): Boolean;
  529.     function OpenVolume( Index: Integer ): Boolean;
  530.     function OpenNextVolume: Boolean;
  531.     function OpenLastVolume: Boolean;
  532.   public
  533.     constructor Create( Owner: TSevenZip; sz: Widestring; asArchive: Boolean );
  534.     destructor Destroy; override;
  535.     function Seek( Offset: Int64; SeekOrigin: DWORD; NewPosition: PInt64 ): Integer; stdcall;
  536.     function Read( var Data; Size: DWORD; ProcessedSize: PDWORD ): Integer; stdcall;
  537.     function ReadPart( var Data; Size: DWORD; ProcessedSize: PDWORD ): Integer; stdcall;
  538.     function GetSize( var Size: Int64 ): Integer; stdcall;
  539.   end;
  540. // -----------------------------------------------------------------------------
  541.   TMyArchiveUpdateCallback = class( TInterfacedObject, IArchiveUpdateCallback, ICryptoGetTextPassword2, IProgress )
  542.     FSevenZip: TSevenZip;
  543.     Files: TWideStringArray;//TStringList;
  544.     Files_size: array of int64;
  545.     Files_Date: array of TFiletime;
  546.     Files_Attr: array of Cardinal;
  547.     FProgressFile: Widestring;
  548.     FProgressFilePos: int64;
  549.     FprogressFileSize: int64;
  550.     FLastPos: int64;
  551.     RootDir: WideString;
  552.     FPassword: WideString;
  553. //    FIncludeDriveletter: Boolean;
  554.     constructor Create( Owner: TSevenZip );
  555. //    destructor destroy;
  556. //    function EnumProperties( var enumerator: IEnumSTATPROPSTG ): Integer; stdcall;
  557.     function GetUpdateItemInfo(
  558.       index: DWORD;
  559.       newData: PInteger; // 1 - new data, 0 - old data
  560.       newProperties: PInteger; // 1 - new properties, 0 - old properties
  561.       indexInArchive: PDWORD // -1 if there is no in archive, or if doesn't matter
  562.     ): Integer; stdcall;
  563.     function GetProperty( index: DWORD; propID: PROPID; value: PPROPVARIANT ): Integer; stdcall;
  564.     function GetStream( index: DWORD; var inStream: ISequentialInStream ): Integer; stdcall;
  565.     function SetOperationResult( operationResult: Integer ): Integer; stdcall;
  566. // Shadow 29.11.2006
  567.     function CryptoGetTextPassword2( passwordIsDefined: PInteger; var Password: PWideChar ): Integer; stdcall;
  568.     function SetTotal( total: Int64 ): Integer; stdcall;
  569.     function SetCompleted( const completeValue: PInt64 ): Integer; stdcall;
  570.   end;
  571.   TMyArchiveExtractCallback = class( TInterfacedObject, IArchiveExtractCallback, ICryptoGetTextPassword )
  572.     FSevenzip: TSevenzip;
  573.     FExtractDirectory: Widestring;
  574.     FProgressFile: Widestring;
  575.     FProgressFilePos: int64;
  576.     FProgressFileSize: int64;
  577.     FLastPos: int64;
  578.     FFilestoextract: int64;
  579.     FLastFileToExt: Boolean;
  580.     FAllFilesExt: Boolean;
  581.     FPassword: WideString;
  582.     constructor Create( Owner: TSevenZip );
  583.     function GetStream( index: DWORD; out outStream: ISequentialOutStream; askExtractMode: DWORD ): Integer; stdcall;
  584.     // GetStream OUT: S_OK - OK, S_FALSE - skeep this file
  585.     function PrepareOperation( askExtractMode: Integer ): Integer; stdcall;
  586.     function SetOperationResult( resultEOperationResult: Integer ): Integer; stdcall;
  587.     function SetTotal( total: Int64 ): Integer; stdcall;
  588.     function SetCompleted( const completeValue: PInt64 ): Integer; stdcall;
  589. // Shadow 29.11.2006
  590.     function CryptoGetTextPassword( var Password: PWideChar ): Integer; stdcall;
  591.   end;
  592.   TMyArchiveOpenCallback = class( TInterfacedObject, IArchiveOpenCallback, ICryptoGetTextPassword )
  593.     FSevenzip: TSevenzip;
  594.     FPassword: WideString;
  595.     constructor Create( Owner: TSevenZip );
  596.     function SetTotal( const files: Int64; const bytes: Int64 ): Integer; stdcall;
  597.     function SetCompleted( const files: Int64; const bytes: Int64 ): Integer; stdcall;
  598.     function CryptoGetTextPassword( var Password: PWideChar ): Integer; stdcall;
  599.   end;
  600. //----------------------------------------------------------------------------------------------------
  601. //----------------------------------------------------------------------------------------------------
  602. //--------------END SevenZip Interface--------------------------------------------------------
  603. //----------------------------------------------------------------------------------------------------
  604. //----------------------------------------------------------------------------------------------------
  605.   
  606.   
  607. //----------------------------------------------------------------------------------------------------  
  608. //----------------------------------------------------------------------------------------------------  
  609. //--------------Start SevenZip VCL -------------------------------------------------------------  
  610. //----------------------------------------------------------------------------------------------------  
  611. //----------------------------------------------------------------------------------------------------  
  612. //type
  613.   TListfileEvent = procedure( Sender: TObject; Filename: Widestring; Fileindex,FileSizeU,FileSizeP,Fileattr,Filecrc:cardinal;Filemethod:Widestring ;FileTime:double ) of object;
  614.   TExtractfileEvent = procedure( Sender: TObject; Filename: Widestring; Filesize:int64 ) of object;
  615.   TAddFileEvent = procedure( Sender: TObject; Filename: Widestring; Filesize:int64 ) of object;
  616.   TPreProgressEvent = procedure( Sender: TObject; MaxProgress: int64 ) of object;
  617.   TProgressEvent = procedure( Sender: TObject; Filename: Widestring; FilePosArc,FilePosFile: int64 ) of object;
  618.   TMessageEvent = procedure( Sender: TObject; ErrCode: Integer; Message: string;Filename:Widestring )  of object;
  619. //  TCRC32ErrorEvent = procedure( Sender: TObject; ForFile: string;  FoundCRC, ExpectedCRC: LongWord; var DoExtract: Boolean ) of object;
  620. //  TCommentEvent = procedure( Sender: TObject;Comment: string; ) of object;
  621.   TSetNewNameEvent = procedure( Sender: TObject; var OldFileName: WideString ) of object;
  622.   TExtractOverwrite = procedure( Sender: TObject; FileName: WideString; var DoOverwrite: Boolean ) of object;
  623. //type
  624.   TSevenZip = class( TComponent )
  625.   private
  626.     FErrCode: Integer;
  627.     FHandle: HWND;
  628. //    FMessage: Widestring; // Not used now ErikGG 08.11.06
  629.     FExtrBaseDir: Widestring;
  630.     FSevenZipFileName: Widestring;
  631.     FComment: Widestring;
  632.     FRootDir: Widestring;
  633.     Ffiles: TWideStringList_;
  634.     { Event variables }
  635.     FOnProgress: TProgressEvent;
  636.     FOnPreProgress: TPreProgressEvent;
  637.     FOnMessage: TMessageEvent;
  638.     FOnlistfile: TlistfileEvent;
  639.     FOnextractfile: TextractfileEvent;
  640.     FOnaddfile: TaddfileEvent;
  641.     FOnSetAddName: TSetNewNameEvent;
  642.     FOnSetExtractName: TSetNewNameEvent;
  643.     FOnExtractOverwite: TExtractOverwrite;
  644.     FAddOptions: Addopts;
  645.     FExtractOptions: Extractopts;
  646.     FNumberOfFiles: Integer;
  647.     FIsSFX: Boolean;
  648.     FSFXOffset: Int64;
  649.     FSFXCreate: Boolean;
  650.     FSFXModule: Widestring;
  651.     FCompresstype: TCompresstype;
  652.     FCompstrength: TCompressStrength;
  653.     FLZMAStrength: TLZMAStrength;
  654.     FPPMDSize: TPPMDSize;
  655.     FPPMDMem: TPPMDMem;
  656.     FMainCancel: Boolean;
  657. // Shadow 28.11.2006
  658.     F7zaLibh: THandle;
  659. {$IFDEF UseRes7zdll}
  660.     mp_MemoryModule: PBTMemoryModule;
  661.     mp_DllData: Pointer;
  662.     m_DllDataSize: Integer;
  663. {$ENDIF}
  664.     FCreateObject: TCreateObjectFunc;
  665.     FVolumeSize: Integer;
  666.     FOnOpenVolume: TOpenVolume;
  667.     FPassword: WideString;
  668.     { Private "helper" functions }
  669. //    procedure LogMessage( var msg: TMessage ); message 9999;
  670.     procedure ResetCancel;
  671.     function AppendSlash( sDir: widestring ): widestring;
  672.     procedure SetVolumeSize( const Value: Integer );
  673.     procedure SetSFXCreate( const Value: Boolean );
  674.   protected
  675.     inA: IInArchive;
  676.     outA: IOutArchive;
  677.     sp: ISetProperties;
  678.   public
  679.     constructor Create( AOwner: TComponent ); override;
  680.     destructor Destroy; override;
  681.     { Public Properties ( run-time only ) }
  682.     property Handle: HWND read fHandle write fHandle;
  683.     property ErrCode: Integer read fErrCode write fErrCode;
  684.     property IsSFX: Boolean read FIsSFX write FIsSFX;
  685.     property SFXOffset: int64 read FSFXOffset write FSFXOffset;
  686.     property SevenZipComment: Widestring read Fcomment write FComment;
  687.     property Files: TWideStringList_ read Ffiles write ffiles;
  688.     { Public Methods }
  689.     function Add: Integer;
  690.     function Extract( TestArchive:Boolean=False ): Integer;
  691.     function List: Integer;
  692.     procedure Cancel;
  693.     function GetIndexByFilename( FileToExtract:Widestring ): Integer;
  694.     function SFXCheck( Fn:Widestring ): Boolean;
  695.     function ConvertSFXto7z( Fn:Widestring ): boolean;
  696.     function Convert7ztoSFX( Fn:Widestring ): boolean;
  697.   published
  698.     { Public properties that also show on Object Inspector }
  699.     property AddRootDir: Widestring read FRootDir write FRootDir;
  700.     property SFXCreate: Boolean read FSFXCreate write SetSFXCreate;
  701.     property SFXModule: Widestring read FSFXModule write FSFXModule;
  702.     property AddOptions: AddOpts read FAddOptions write FAddOptions;
  703.     property ExtractOptions: ExtractOpts read FExtractOptions write FExtractOptions;
  704.     property ExtrBaseDir: Widestring read FExtrBaseDir write FExtrBaseDir;
  705.     property LZMACompressType: TCompresstype read FCompresstype write FCompresstype;
  706.     property LZMACompressStrength: TCompressStrength read FCompstrength write FCompstrength;
  707.     property LZMAStrength: TLZMAStrength read FLZMAStrength write FLZMAstrength;
  708.     property LPPMDmem: TPPMDmem read FPPMDmem write FPPMDmem;
  709.     property LPPMDsize: TPPMDsize read FPPMDsize write FPPMDsize;
  710.     property SZFileName: Widestring read FSevenZipFileName write FSevenZipFilename;
  711.     property NumberOfFiles: Integer read FNumberOfFiles write FNumberOfFiles;
  712. // Shadow 29.11.2006
  713.     property VolumeSize: Integer read FVolumeSize write SetVolumeSize;
  714.     property Password: WideString read FPassword write FPassword;
  715.     { Events }
  716.     property OnListfile: TlistfileEvent read FOnlistfile write FOnlistfile;
  717.     property OnAddfile: TaddfileEvent read FOnaddfile write FOnaddfile;
  718.     property OnExtractfile: TextractfileEvent read FOnextractfile write FOnextractfile;
  719.     property OnProgress: TProgressEvent read FOnProgress  write FOnProgress;
  720.     property OnPreProgress: TPreProgressEvent read FOnPreProgress  write FOnPreProgress;
  721.     property OnMessage: TMessageEvent read fOnMessage write fOnMessage;
  722.     property OnSetAddName: TSetNewNameEvent read FOnSetAddName write FOnSetAddName;
  723.     property OnSetExtractName: TSetNewNameEvent read FOnSetExtractName write FOnSetExtractName;
  724.     property OnExtractOverwrite: TExtractOverwrite read FOnExtractOverwite write FOnExtractOverwite;
  725.     property OnOpenVolume: TOpenVolume read FOnOpenVolume write FOnOpenVolume;
  726.   end;
  727. // jjw 18.10.2006 FCreateobject - function CreateObject( const clsid: PGUID; const iid: PGUID; out _out ): Integer; stdcall; external '7za.dll';
  728. function PropTypeToString( propType: Integer ): string;
  729. function PropIDToString( propID: Integer ): string;
  730. procedure Log( sz: string );
  731. function FileTimeToDateTime( const rFileTime: TFileTime; const Localize: Integer = 0 ): TDateTime;
  732. procedure SortDWord( var A: array of DWord; iLo, iHi: DWord );
  733. function DriveIsRemovable( Drive: WideString ): Boolean;
  734. function TryStrToInt_( const S: string; out Value: Integer ): Boolean;
  735. //Unicode procedures
  736. function UppercaseW_( s:WideString ):Widestring;
  737. function GetFileSizeandDateTime_Int64( fn: Widestring; var fs:int64; var ft:Tfiletime; var fa:Integer ): int64;
  738. function FileExists_( fn: Widestring ): Boolean;
  739. function createfile_(lpFileName:Pwidechar; Access:Cardinal; Share:Cardinal;SecAttr:PSecurityattributes;
  740.                      CreationDisposition:Cardinal;Flags:Cardinal;Temp:Cardinal) : integer;
  741. procedure Register;
  742. var FMainhandle: HWND; //for debug messages
  743. var isUnicode : Boolean;
  744. implementation
  745. uses
  746.   Forms, CommDlg;
  747. //--------------------------------------------------------------------------------------------------
  748. //-------------------Start UniCode procedures-------------------------------------------------------
  749. //--------------------------------------------------------------------------------------------------
  750. function isEqualW( s1, s2: WideString ): Boolean;
  751. var
  752.   i: Integer;
  753. begin
  754.   Result := FALSE;
  755.   if Length( s1 ) <> Length( s2 ) then Exit;
  756.   for i := 1 to Length( s1 ) do if WideChar( s1[ i ] ) <> WideChar( s2[ i ] ) then Exit;
  757.   Result := TRUE;
  758. end;
  759. function FileExists_( fn: Widestring ): Boolean;
  760. var
  761.  fs:int64;
  762.  ft:Tfiletime;
  763.  fa:Integer;
  764. begin
  765.  if isUnicode then
  766.    Result := ( GetFileSizeandDateTime_Int64( fn,fs,ft,fa ) > -1 )
  767.   else
  768.    Result := fileexists(string(fn));
  769. end;
  770. function PrevDir( Path: WideString ): WideString;
  771. var
  772.   l: Integer;
  773. begin
  774.   l := Length( Path );
  775.   if ( l > 0 ) and ( Path[ l ] = '' ) then Dec( l );
  776.   while Path[ l ] <> '' do Dec( l );
  777.   Result := Copy( Path, 1, l );
  778. end;
  779. function ClearSlash( Path: WideString ): WideString;
  780. var
  781.   l: Integer;
  782. begin
  783.   l := Length( Path );
  784.   if Path[ l ] = '' then Dec( l );
  785.   Result := Copy( Path, 1, l );
  786. end;
  787. function DirectoryExistsW( const Directory: WideString ): Boolean;
  788. var
  789.   Code: Integer;
  790. begin
  791.   Code := GetFileAttributesW( PWideChar( Directory ) );
  792.   Result := ( Code <> -1 ) and ( FILE_ATTRIBUTE_DIRECTORY and Code <> 0 );
  793. end;
  794. //START function from TNTControls http://www.tntware.com/
  795. function StrScanWide( const Str: PWideChar; Chr: WideChar ): PWideChar;
  796. begin
  797.   Result := Str;
  798.   while Result^ <> Chr do
  799.   begin
  800.     if Result^ = #0 then
  801.     begin
  802.       Result := nil;
  803.       Exit;
  804.     end;
  805.     Inc( Result );
  806.   end;
  807. end;
  808. function LastDelimiterW( const Delimiters, S: WideString ): Integer;
  809. var
  810.   P: PWideChar;
  811. begin
  812.   Result := Length( S );
  813.   P := PWideChar( Delimiters );
  814.   while Result > 0 do
  815.   begin
  816.     if ( S[ Result ] <> #0 ) and ( StrScanWide( P, S[ Result ] ) <> nil ) then
  817.       Exit;
  818.     Dec( Result );
  819.   end;
  820. end;
  821. function ChangeFileExtW( const FileName, Extension: WideString ): WideString;
  822. var
  823.   I: Integer;
  824. begin
  825.   I := LastDelimiterW( '.:',Filename );
  826.   if ( I = 0 ) or ( FileName[ I ] <> '.' ) then I := MaxInt;
  827.   Result := Copy( FileName, 1, I - 1 ) + Extension;
  828. end;
  829. function ExtractFilePathW( const FileName: WideString ): WideString;
  830. var
  831.   I: Integer;
  832. begin
  833.   I := LastDelimiterW( ':', FileName );
  834.   Result := Copy( FileName, 1, I );
  835. end;
  836. function ExtractFileNameW( const FileName: WideString ): WideString;
  837. var
  838.   I: Integer;
  839. begin
  840.   I := LastDelimiterW( ':', FileName );
  841.   Result := Copy( FileName, I + 1, MaxInt );
  842. end;
  843. function ExtractFileExtW( const FileName: WideString ): WideString;
  844. var
  845.   I: Integer;
  846. begin
  847.   I := LastDelimiterW( '.:', FileName );
  848.   if ( I > 0 ) and ( FileName[ I ] = '.' ) then
  849.     Result := Copy( FileName, I, MaxInt ) else
  850.     Result := '';
  851. end;
  852. //END function from TNTControls http://www.tntware.com/
  853. function GetFileSizeandDateTime_Int64( fn: Widestring; var fs:int64; var ft:Tfiletime; var fa:Integer ): int64;
  854. var
  855.   FindDataW: _Win32_Find_Dataw;
  856.   FindDataA: _Win32_Find_DataA;
  857.   SearchHandle: THandle;
  858. begin
  859.   Result := 0;
  860.   if isUnicode then
  861.    SearchHandle := FindFirstFilew( PWideChar( fn ), FindDataW )
  862.   else
  863.     SearchHandle := FindFirstFile( PAnsiChar( Ansistring( fn ) ), FindDataA );
  864.   if SearchHandle = INVALID_HANDLE_VALUE then
  865.    begin
  866.     Result := -1;
  867.     fs := -1;
  868.     fa := -1;
  869.     ft.dwLowDateTime := 0;
  870.     ft.dwHighDateTime := 0;
  871.     exit;
  872.    end;
  873.   if isUnicode then
  874.    begin
  875.      LARGE_Integer( Result ).LowPart := FindDataW.nFileSizeLow;
  876.      LARGE_Integer( Result ).HighPart := FindDataW.nFileSizeHigh;
  877.      LARGE_Integer( fs ).LowPart := FindDataW.nFileSizeLow;
  878.      LARGE_Integer( fs ).HighPart := FindDataW.nFileSizeHigh;
  879.      ft.dwLowDateTime  := FinddataW.ftLastWriteTime.dwLowDateTime;
  880.      ft.dwHighDateTime := FinddataW.ftLastWriteTime.dwHighDateTime;
  881.      fa := FinddataW.dwFileAttributes;
  882.    end
  883.   else
  884.    begin
  885.      LARGE_Integer( Result ).LowPart := FindDataA.nFileSizeLow;
  886.      LARGE_Integer( Result ).HighPart := FindDataA.nFileSizeHigh;
  887.      LARGE_Integer( fs ).LowPart := FindDataA.nFileSizeLow;
  888.      LARGE_Integer( fs ).HighPart := FindDataA.nFileSizeHigh;
  889.      ft.dwLowDateTime  := FinddataA.ftLastWriteTime.dwLowDateTime;
  890.      ft.dwHighDateTime := FinddataA.ftLastWriteTime.dwHighDateTime;
  891.      fa := FinddataA.dwFileAttributes;
  892.    end;
  893.    
  894.   Windows.FindClose( SearchHandle );
  895. end;
  896. function ForceDirectoriesW( Path: WideString; Attr: Word ): Boolean;
  897. var
  898.   E: EInOutError;
  899. begin
  900.   Result := TRUE;
  901.   if Path = '' then begin
  902.     E := EInOutError.Create( 'Unable to create directory' );
  903.     E.ErrorCode := 3;
  904.     raise E;
  905.   end;
  906.   Path := ClearSlash( Path );
  907.   if DirectoryExistsW( Path ) then Exit;
  908.   if ( Length( Path ) < 3 ) or DirectoryExistsw( Path )
  909.     or ( ExtractFilePath( Path ) = Path ) then Exit; // avoid 'xyz:' problem.
  910.   Result := ForceDirectoriesW( PrevDir( Path ), 0 ) and CreateDirectoryW( PWideChar( Path ), nil );
  911.   if Result and ( Attr > 0 ) then SetFileAttributesW( PWideChar( Path ), Attr );
  912. end;
  913. function UppercaseW_( s:WideString ):Widestring;
  914. begin
  915.   Result := S;
  916.   if Length( Result ) > 0 then
  917.     CharUpperBuffW( PWideChar( Result ), Length( Result ) );
  918. end;
  919. //--------------------------------------------------------------------------------------------------
  920. //-------------------End UniCode procedures---------------------------------------------------------
  921. //--------------------------------------------------------------------------------------------------
  922. //--------------------------------------------------------------------------------------------------
  923. //-------------------Start Twidestringlist_-----------------------------------------------------------
  924. //--------------------------------------------------------------------------------------------------
  925. procedure TWideStringList_.AddString( s: WideString );
  926. var i:Longword;
  927. begin
  928.  i := length( WStrings );
  929.  Setlength( WStrings,i+1 );
  930.  WStrings[ i ] := s;
  931.  Count := i+1;
  932. end;
  933. procedure TWideStringList_.RemoveString( s: WideString );
  934. var
  935.   i: LongWord;
  936.   f: Boolean;
  937. begin
  938.   f := FALSE;
  939.   s := UpperCase( s );
  940.   for i := Low( WStrings ) to High( WStrings ) do begin
  941.     if isEqualW( UppercaseW_( WStrings[ i ] ), s ) then begin
  942.       f := TRUE;
  943.       Break;
  944.     end;
  945.   end;
  946.   if f then begin
  947.     WStrings[ i ] := WStrings[ High( WStrings ) ];
  948.     WStrings[ High( WStrings ) ] := '';
  949.     SetLength( WStrings, Length( WStrings ) - 1 );
  950.     Dec( Count );
  951.   end;
  952. end;
  953. Procedure TWideStringList_.Clear;
  954. begin
  955.  Setlength( WStrings,0 );
  956.  Count := 0;
  957. end;
  958. Constructor TWideStringList_.Create;
  959. begin
  960.  clear;
  961. end;
  962. //--------------------------------------------------------------------------------------------------
  963. //-------------------END Twidestringlist_-------------------------------------------------------------
  964. //--------------------------------------------------------------------------------------------------
  965. //--------------------------------------------------------------------------------------------------
  966. //  Start common functions
  967. //------------------------------------------------------------------------------------------------
  968. function createfile_(lpFileName:Pwidechar; Access:Cardinal; Share:Cardinal;SecAttr:PSecurityattributes;
  969.                      CreationDisposition:Cardinal;Flags:Cardinal;Temp:Cardinal) : integer;
  970. begin
  971. if isUnicode then
  972.  Result := createfilew(lpFilename,access,share,SecAttr,Creationdisposition,flags,temp)
  973. else
  974.  Result := createfilea(PAnsichar( AnsiString(lpFilename)),access,share,SecAttr,Creationdisposition,flags,temp)
  975. end;
  976. function TSevenZip.AppendSlash( sDir: widestring ): widestring;
  977. begin
  978.   if ( sDir <> '' ) and ( sDir[ Length( sDir ) ] <> '' ) then
  979.     Result := sDir + ''
  980.   else
  981.     Result := sDir;
  982. end;
  983. procedure TSevenZip.SetVolumeSize( const Value: Integer );
  984. begin
  985. // Shadow 27.11.2006
  986.   if not FSFXCreate then
  987.     FVolumeSize := Value
  988.   else begin
  989.     if ( Value > 0 ) and ( Value < FSFXOffset ) then
  990.       FVolumeSize := FSFXOffset + 7
  991.     else FVolumeSize := Value;
  992.   end;
  993. end;
  994. procedure TSevenZip.SetSFXCreate( const Value: Boolean );
  995.   function FileSizeW( fn: WideString ): DWORD;
  996.   var
  997.     f: Integer;
  998.   begin
  999.     Result := 0;
  1000.     f := CreateFile_( PwideChar( fn ), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0 );
  1001.     if f <= 0 then Exit;
  1002.     try
  1003.       Result := FileSeek( f, 0, soFromEnd );
  1004.     finally
  1005.       FileClose( f );
  1006.     end;
  1007.   end;
  1008. var
  1009.   s: Int64;
  1010. begin
  1011. // Shadow 27.11.2006
  1012.   FSFXCreate := FALSE;
  1013.   if Value then begin
  1014.     s := FileSizeW( FSFXModule );
  1015.     if ( s > 0 ) then begin // FileExists
  1016.       if ( ( FVolumeSize > 0 ) and ( FVolumeSize < s + 7 ) ) then FVolumeSize := s + 7;
  1017.       FSFXOffset := s;
  1018.       FSFXCreate := TRUE;
  1019.     end;
  1020.   end;
  1021. end;
  1022. function FileTimeToDateTime( const rFileTime: TFileTime; const Localize: Integer = 0 ): TDateTime;
  1023. var
  1024.   dOffset: Double;
  1025.   rWork: TFileTime;
  1026. begin
  1027.   // offset to or from local time
  1028.   if Localize > 0 then
  1029.     FileTimeToLocalFileTime( rFileTime, rWork )
  1030.   else if Localize < 0 then
  1031.     LocalFileTimeToFileTime( rFileTime, rWork )
  1032.   else begin
  1033.     rWork := rFileTime;
  1034.   end;
  1035.   dOffset := 0.0000001 * ( ( Int64( rWork.dwHighDateTime ) shl 32 ) or rWork.dwLowDateTime );
  1036.   dOffset := dOffset / ( 60 * 60 * 24 );
  1037.   Result := EncodeDate( 1601, 1, 1 ) + dOffset;
  1038. end;
  1039. procedure SortDWord( var A: array of DWord; iLo, iHi: DWord );
  1040. var
  1041.   Lo, Hi, Mid, T: DWord;
  1042. begin
  1043.     Lo := iLo;
  1044.     Hi := iHi;
  1045.     Mid := A[ ( Lo + Hi ) div 2 ];
  1046.     repeat
  1047.       while A[ Lo ] < Mid do Inc( Lo );
  1048.       while A[ Hi ] > Mid do Dec( Hi );
  1049.       if Lo <= Hi then
  1050.       begin
  1051.         T := A[ Lo ];
  1052.         A[ Lo ] := A[ Hi ];
  1053.         A[ Hi ] := T;
  1054.         Inc( Lo );
  1055.         if Hi > 0 then Dec( Hi ); //Using DWord and not Integers
  1056.       end;
  1057.     until Lo > Hi;
  1058.     if Hi > iLo then SortDWord( A, iLo, Hi );
  1059.     if Lo < iHi then SortDWord( A, Lo, iHi );
  1060. end;
  1061. function DriveIsRemovable( Drive: WideString ): Boolean;
  1062. var
  1063.   DT: Cardinal;
  1064. begin
  1065.   DT := GetDriveTypeW( PWideChar( Drive ) );
  1066.   Result := ( DT <> DRIVE_FIXED );
  1067. end;
  1068. function TryStrToInt_( const S: string; out Value: Integer ): Boolean;
  1069. var
  1070.    E: Integer;
  1071. begin
  1072.    Val( S, Value, E );
  1073.    Result := ( E = 0 );
  1074. end;
  1075. //------------------------------------------------------------------------------------------------
  1076. //  End common functions
  1077. //--------------------------------------------------------------------------------------------------
  1078. //--------------------------------------------------------------------------------------------------
  1079. //--------------------------------------------------------------------------------------------------
  1080. //-------------------Start SevenZip Interface -----------------------------------------------
  1081. //--------------------------------------------------------------------------------------------------
  1082. //--------------------------------------------------------------------------------------------------
  1083. function TInterfacedObject.QueryInterface( const IID: TGUID; out Obj ): HResult;
  1084. const
  1085.   E_NOINTERFACE = HResult( $80004002 );
  1086. begin
  1087.   if GetInterface( IID, Obj ) then
  1088.   begin
  1089.     Result := 0;
  1090.     Log( 'INTERFACEOK:' + ClassName + ' ' + GUIDToString( IID ) );
  1091.   end else
  1092.   begin
  1093.     Result := E_NOINTERFACE;
  1094.     Log( '  NOINTERFACE: ' + ClassName + ' ' + GUIDToString( IID ) );
  1095.   end;
  1096. end;
  1097. function TInterfacedObject._AddRef: Integer;
  1098. begin
  1099.   Result := InterlockedIncrement( FRefCount );
  1100. end;
  1101. function TInterfacedObject._Release: Integer;
  1102. begin
  1103.   Result := InterlockedDecrement( FRefCount );
  1104.   if Result = 0 then
  1105.     Destroy;
  1106. end;
  1107. procedure TInterfacedObject.AfterConstruction;
  1108. begin
  1109. // Release the constructor's implicit refcount
  1110.   InterlockedDecrement( FRefCount );
  1111. end;
  1112. procedure TInterfacedObject.BeforeDestruction;
  1113. begin
  1114.   //if RefCount <> 0 then Error( reInvalidPtr );
  1115. end;
  1116. // Set an implicit refcount so that refcounting
  1117. // during construction won't destroy the object.
  1118. class function TInterfacedObject.NewInstance: TObject;
  1119. begin
  1120.   Result := inherited NewInstance;
  1121.   TInterfacedObject( Result ).FRefCount := 1;
  1122. end;
  1123. constructor TMyArchiveUpdateCallback.Create( Owner: TSevenZip );
  1124. begin
  1125.   inherited Create;
  1126.   FSevenzip := Owner;
  1127. // Shadow 29.11.2006
  1128.   if Assigned( FSevenzip ) then
  1129.     FPassword := FSevenzip.Password
  1130.   else FPassword := '';
  1131. end;
  1132. function TMyArchiveUpdateCallback.GetUpdateItemInfo( index: DWORD;
  1133.   newData: PInteger; // 1 - new data, 0 - old data
  1134.   newProperties: PInteger; // 1 - new properties, 0 - old properties
  1135.   indexInArchive: PDWORD // -1 if there is no in archive, or if doesn't matter
  1136.   ): Integer; stdcall;
  1137. begin
  1138. //  Log( Format( 'TMyArchiveUpdateCallback.GetUpdateItemInfo( %d )', [ index ] ) );
  1139.   if newData <> nil then newData^ := 1;
  1140.   if newProperties <> nil then newProperties^ := 1;
  1141.   if indexInArchive <> nil then indexInArchive^ := DWORD( -1 );
  1142.   Result := S_OK;
  1143. end;
  1144. function TMyArchiveUpdateCallback.CryptoGetTextPassword2( passwordIsDefined: PInteger; var Password: PWideChar ): Integer;
  1145. begin
  1146.   if Length( FPassword ) > 0 then begin
  1147.     passwordIsDefined^ := Integer( Bool( TRUE ) );
  1148.     Password := SysAllocString( @FPassword[ 1 ] );
  1149.     Result := S_OK;
  1150.   end else begin
  1151.     passwordIsDefined^ := Integer( Bool( FALSE ) );
  1152.     Result := S_OK;
  1153.   end;
  1154. end;
  1155. function TMyArchiveUpdateCallback.GetProperty( index: DWORD; propID: PROPID; value: PPROPVARIANT ): Integer; stdcall;
  1156. var
  1157.   sz: WideString;
  1158. begin
  1159.   Log( Format( 'TMyArchiveUpdateCallback.GetProperty( %d, %s ( %d ), %.8x )', [ index, PropIDToString( propID ), propID, Integer( value ) ] ) );
  1160.   Result := S_OK;
  1161.   case propID of
  1162.     //kpidPath ( 3 ) VT_BSTR ( 8 )
  1163.     kpidPath:
  1164.     begin
  1165.       value^.vt := VT_BSTR;
  1166. //get relative path if wanted
  1167.       sz := Files[ index ];
  1168.       if rootdir <> '' then
  1169.       begin
  1170.         if Uppercasew_( copy( sz,1,length( rootdir ) ) ) = rootdir then
  1171.           delete( sz,1,length( rootdir ) );
  1172.       end;
  1173. //User set filename in archive if wanted
  1174.       if assigned( Fsevenzip.OnSetAddName ) then
  1175.         Fsevenzip.OnSetAddName( Fsevenzip, sz );
  1176. //remove drive / Include drive if wanted
  1177.       if sz[ 2 ] = ':' then
  1178.         begin
  1179.          if char( sz[ 1 ] ) in [ 'A'..'Z','a'..'z' ] then
  1180.            if ( AddIncludeDriveLetter in Fsevenzip.FAddOptions ) then //include
  1181.             delete( sz,2,1 )
  1182.            else
  1183.              delete( sz,1,3 );
  1184.         end;
  1185. //just store filename
  1186.       if ( AddStoreOnlyFilename in Fsevenzip.FAddOptions ) then
  1187.         sz := ExtractFileNameW( sz );
  1188. //rg 07.11.2006 StringToOleStr( )
  1189.       value^.bstrVal := Pwidechar( sz );
  1190.     end;
  1191.     //kpidAttributes ( 9 ) VT_UI4 ( 19 )
  1192.     kpidAttributes:
  1193.     begin
  1194.       value^.vt := VT_UI4;
  1195.       value^.ulVal := Files_Attr[ index ];//filegetattr( files[ index ] );
  1196.     end;
  1197.     kpidCreationTime:
  1198.     begin
  1199.       value^.vt := VT_FILETIME;
  1200.       value^.filetime.dwLowDateTime := 0;
  1201.       value^.filetime.dwHighDateTime := 0;
  1202.     end;
  1203.     //kpidLastWriteTime ( 12 ) VT_FILETIME ( 64 )
  1204.     kpidLastWriteTime:
  1205.     begin
  1206.       value^.vt := VT_FILETIME;
  1207.       value^.filetime.dwLowDateTime := Files_Date[ index ].dwLowDateTime;;
  1208.       value^.filetime.dwHighDateTime := Files_Date[ index ].dwHighDateTime;
  1209.     end;
  1210.     kpidIsFolder:
  1211.     begin
  1212.       value^.vt := VT_BOOL;
  1213.       value^.boolVal := ( Files_Attr[ index ] and faDirectory ) <> 0; //false
  1214.     end;
  1215.     kpidIsAnti:
  1216.     begin
  1217.       value^.vt := VT_BOOL;
  1218.       value^.boolVal := False;
  1219.     end;
  1220.     //kpidSize ( 7 ) VT_UI8 ( 21 )
  1221.     kpidSize:
  1222.     begin
  1223.       value^.vt := VT_UI8;
  1224.       value^.uhVal.QuadPart := Files_size[ index ];
  1225.     end;
  1226.   else
  1227.     Log( 'Asking for unknown property' );
  1228.     Result := S_FALSE;
  1229.   end;
  1230. end;
  1231. function TMyArchiveUpdateCallback.GetStream( index: DWORD; var inStream: ISequentialInStream ): Integer; stdcall;
  1232. begin
  1233.   Log( 'TMyArchiveUpdateCallback.GetStream' );
  1234.   Fprogressfile := files[ index ];
  1235.   Fprogressfilesize := files_size[ index ];
  1236.   Fprogressfilepos := 0;
  1237.   inStream := TMyStreamReader.Create( FSevenZip, Files[ index ], FALSE );
  1238.   Result := S_OK;
  1239. end;
  1240. function TMyArchiveUpdateCallback.SetOperationResult( operationResult: Integer ): Integer; stdcall;
  1241. begin
  1242.   Log( Format( 'TMyArchiveUpdateCallback.SetOperationResult( %d )', [ operationResult ] ) );
  1243.   Result := S_OK;
  1244. end;
  1245. function TMyArchiveUpdateCallback.SetTotal( total: Int64 ): Integer; stdcall;
  1246. begin
  1247.   Log( Format( 'TMyArchiveUpdateCallback.SetTotal( %d )', [ total ] ) );
  1248.   Result := S_OK;
  1249. end;
  1250. function TMyArchiveUpdateCallback.SetCompleted( const completeValue: PInt64 ): Integer; stdcall;
  1251. begin
  1252. /// Progressfile - Newfile
  1253. /// Do it here because it works with Multithreaded 7za interaction.
  1254.   Log( Format( 'TMyArchiveUpdateCallback.SetCompleted( %d )', [ completeValue^ ] ) );
  1255. //fileprogress
  1256.    if ( FProgressFilePos = 0 ) then
  1257.       if assigned( Fsevenzip.OnAddFile ) then Fsevenzip.onAddFile( Fsevenzip,FProgressFile,FProgressFileSize );
  1258.    FProgressFilePos := FProgressFilePos + ( completeValue^ - FLastPos );
  1259.    FLastPos := completeValue^;
  1260. //full and file progress position
  1261.    if assigned( Fsevenzip.OnProgress ) then Fsevenzip.OnProgress( Fsevenzip,FProgressFile,completeValue^,FProgressFilePos );
  1262.   Result := S_OK;
  1263. //rg 24.06
  1264. //User cancel operation
  1265.   if FSevenzip.FMainCancel then
  1266.    begin
  1267.      if assigned( Fsevenzip.onMessage ) then Fsevenzip.OnMessage( Fsevenzip,6,'User canceled operation',FProgressFile );
  1268.      Result := S_FALSE;
  1269.    end;
  1270. end;
  1271. constructor TMyArchiveExtractCallback.Create( Owner: TSevenZip );
  1272. begin
  1273.   inherited Create;
  1274.   FSevenzip := Owner;
  1275. // Shadow 29.11.2006
  1276.   if Assigned( FSevenzip ) then
  1277.     FPassword := FSevenzip.Password
  1278.   else FPassword := '';
  1279. end;
  1280. function TMyArchiveExtractCallback.GetStream( index: DWORD;
  1281.   out outStream: ISequentialOutStream; askExtractMode: DWORD ): Integer; stdcall;
  1282. var
  1283.  path: Propvariant;
  1284.  size: Propvariant;
  1285.  date: Propvariant;
  1286.  attr: Propvariant;
  1287.    sz, origName: Widestring;
  1288.    fe,DoOverwrite: boolean;
  1289. //   fHnd: Integer;
  1290. begin
  1291.   Log( Format( '__TMyArchiveExtractCallback.GetStream( %d, %.8x, %d )', [ index, Integer( outStream ), askExtractMode ] ) );
  1292.   path.vt := VT_EMPTY;
  1293.   size.vt := VT_EMPTY;
  1294.   date.vt := VT_EMPTY;
  1295.   attr.vt := VT_EMPTY;
  1296. //Cancel Operation
  1297.   if self.FSevenzip.FMainCancel then
  1298.    begin
  1299.     outStream := nil;
  1300.     result := S_FALSE;
  1301.     exit;
  1302.    end;
  1303.   Case askExtractMode of
  1304.     kExtract:  begin
  1305.                  FSevenzip.inA.GetProperty( index, kpidPath, path );
  1306.                  FSevenzip.inA.GetProperty( index, kpidSize, size );
  1307.                  FSevenzip.inA.GetProperty( index, kpidattributes, attr );
  1308.                  FSevenzip.inA.GetProperty( index, kpidLastWriteTime, date );
  1309. //rg 23.8.06
  1310.                  if ExtractNoPath in FSevenzip.FExtractOptions then
  1311.                    sz := FExtractDirectory + extractfilenameW( path.bstrVal )
  1312.                   else
  1313.                    sz := FExtractDirectory + path.bstrVal;
  1314.                  origName := sz;
  1315.                  if assigned( Fsevenzip.OnSetExtractName ) then
  1316.                    Fsevenzip.OnSetExtractName( Fsevenzip, sz );
  1317.                  if FileExists_( sz ) then
  1318.                    begin
  1319.                      if assigned( Fsevenzip.OnExtractOverwrite ) then
  1320.                          Fsevenzip.OnExtractOverwrite( Fsevenzip, sz,DoOverwrite );
  1321.                      if not DoOverwrite then
  1322.                       begin
  1323.                        Result := S_OK;
  1324.                        outStream := nil;
  1325.                        exit;
  1326.                       end;
  1327.                     end;
  1328.                     FProgressFile := sz;
  1329.                     FProgressFilePos := 0;
  1330.                     FprogressFileSize := size.uhVal.QuadPart;
  1331.                  if ( attr.uiVal and ( 1 shl 4 ) ) <> 0 then
  1332.                   begin
  1333.                    if isUnicode then
  1334.                      ForceDirectoriesW( sz, attr.uiVal )
  1335.                     else
  1336.                      ForceDirectories(String(sz));
  1337.                   end
  1338.                  else
  1339.                   begin
  1340.                     FFilestoextract := FFilestoextract - 1;
  1341.                     if FFilestoextract = 0 then FLastFileToExt := true;
  1342.                     outStream := nil;
  1343.                     fe := FileExists_( sz );
  1344.                     if ( not fe ) or ( fe and ( ( ExtractOverwrite in FsevenZip.FExtractOptions ) or DoOverwrite ) ) then begin
  1345.                       if isUnicode then
  1346.                         ForceDirectoriesW( ExtractFilePathW( sz ), attr.uiVal )
  1347.                        else
  1348.                         ForceDirectories(extractfilepath( String( sz ) ) );
  1349.                     try
  1350.                       outStream := TMyStreamWriter.Create( sz, FileTimeToDateTime( date.filetime, 2 ), attr.lVal );
  1351.                     except
  1352.                       outStream := nil;
  1353.                       Result := S_FALSE;
  1354.                       Exit;
  1355. // did not work here need another place !
  1356. // if assigned( FsevenZip.onmessage ) then FsevenZip.onmessage( FsevenZip, 2, 'Could not create file', origName );
  1357.                     end;
  1358.                   end;
  1359.               end;
  1360.              end;
  1361.     ktest   : begin
  1362.                  FSevenzip.inA.GetProperty( index, kpidPath, path );
  1363.                  FSevenzip.inA.GetProperty( index, kpidSize, size );
  1364.                  FProgressFile := path.bstrVal;
  1365.                  FProgressFilePos := 0;
  1366.                  FprogressFileSize := size.uhVal.QuadPart ;
  1367.                end;
  1368.     kskip   : begin
  1369.                end;
  1370.   end;
  1371.   Result := S_OK;
  1372. end;
  1373. // GetStream OUT: S_OK - OK, S_FALSE - skeep this file
  1374. function TMyArchiveExtractCallback.PrepareOperation( askExtractMode: Integer ): Integer; stdcall;
  1375. begin
  1376.   Log( Format( 'TMyArchiveExtractCallback.PrepareOperation( %d )', [ askExtractMode ] ) );
  1377.   Result := S_OK;
  1378. end;
  1379. function TMyArchiveExtractCallback.SetOperationResult( resultEOperationResult: Integer ): Integer; stdcall;
  1380. begin
  1381.   Result := S_OK;
  1382.   Log( Format( 'TMyArchiveExtractCallback.SetOperationResult( %d )', [ resultEOperationResult ] ) );
  1383.   case resultEOperationResult of
  1384.     kOK               : ;
  1385.     kUnSupportedMethod: if assigned( Fsevenzip.onmessage ) then Fsevenzip.onmessage( Fsevenzip,4,'Unsupported Method',FProgressFile );
  1386.     kDataError        : if assigned( Fsevenzip.onmessage ) then Fsevenzip.onmessage( Fsevenzip,2,'Data Error',FProgressFile );
  1387.     kCRCError         : if assigned( Fsevenzip.onmessage ) then Fsevenzip.onmessage( Fsevenzip,3,'CRC Error',FProgressFile );
  1388.   end;
  1389.   if FLastFileToExt then FAllFilesExt := true; //no more files to extract, we can stop
  1390. end;
  1391. function TMyArchiveExtractCallback.SetTotal( total: Int64 ): Integer; stdcall;
  1392. begin
  1393.   Log( Format( 'TMyArchiveExtractCallback.SetTotal( %d )', [ total ] ) );
  1394. //all filesizes also skipped ones
  1395.   if FFilestoextract = 0 then // we extract all files, so we set FMaxProgress here
  1396.      if assigned( FSevenzip.OnPreProgress ) then FSevenzip.OnPreProgress( FSevenzip,total );
  1397.   Result := S_OK;
  1398. end;
  1399. function TMyArchiveExtractCallback.SetCompleted( const completeValue: PInt64 ): Integer; stdcall;
  1400. begin
  1401.    if ( FProgressFilePos = 0 ) then
  1402.       if assigned( Fsevenzip.OnExtractFile ) then Fsevenzip.onExtractfile( Fsevenzip,FProgressFile,FProgressFileSize );
  1403.    FProgressFilePos := FProgressFilePos + ( completeValue^ - FLastPos );
  1404.    FLastPos := completeValue^;
  1405. //full and file progress position
  1406.    if assigned( Fsevenzip.OnProgress ) then Fsevenzip.OnProgress( Fsevenzip,FProgressFile,completeValue^,FProgressFilePos );
  1407.   Log( Format( 'TMyArchiveExtractCallback.SetCompleted( %d )', [ completeValue^ ] ) );
  1408.   Result := S_OK;
  1409.   //have all files extracted. Could stop
  1410.   //User cancel operation
  1411.   if self.FAllFilesExt then Result := S_FALSE;
  1412.   if  Fsevenzip.FMainCancel then begin
  1413.      Result := S_FALSE;
  1414.      if assigned( Fsevenzip.onMessage ) then Fsevenzip.OnMessage( Fsevenzip,6,'User canceled operation',FProgressFile );
  1415.    end;
  1416. end;
  1417. function TMyArchiveExtractCallback.CryptoGetTextPassword( var Password: PWideChar ): Integer;
  1418. begin
  1419.   if Length( FPassword ) > 0 then begin
  1420.     Password := SysAllocString( @FPassword[ 1 ] );
  1421.     Result := S_OK;
  1422.   end else Result := S_FALSE;
  1423. end;
  1424. {============ TMyOpenarchiveCallbackReader =================================================}
  1425. function TMyArchiveOpenCallback.CryptoGetTextPassword( var Password: PWideChar ): Integer;
  1426. begin
  1427.   if Length( FPassword ) > 0 then begin
  1428.     Password := SysAllocString( @FPassword[ 1 ] );
  1429.     Result := S_OK;
  1430.   end else Result := S_FALSE;
  1431. end;
  1432. constructor TMyArchiveOpenCallback.Create( Owner: TSevenZip );
  1433. begin
  1434.   inherited Create;
  1435.   FSevenzip := Owner;
  1436. // Shadow 29.11.2006
  1437.   if Assigned( FSevenzip ) then
  1438.     FPassword := FSevenzip.Password
  1439.   else FPassword := '';
  1440. end;
  1441. function TMyArchiveOpenCallback.SetTotal( const files: Int64; const bytes: Int64 ): Integer; stdcall;
  1442. begin
  1443.  // Lifepower (07-Jan-2007):
  1444.  //  Huh? Added some result value to prevent warning.
  1445.  Result:= 0;
  1446. //
  1447. end;
  1448. function TMyArchiveOpenCallback.SetCompleted( const files: Int64; const bytes: Int64 ): Integer; stdcall;
  1449. begin
  1450.  // Lifepower (07-Jan-2007):
  1451.  //  Added some result value to prevent warning.
  1452.  Result:= 0;
  1453. //
  1454. end;
  1455. {============ TMyStreamReader =================================================}
  1456. function TMyStreamReader.Seek( Offset: Int64; SeekOrigin: DWORD; NewPosition: PInt64 ): Integer; stdcall;
  1457. begin
  1458. //  frmMain.mmoLog.Lines.Add( '-> Seek ' + IntToStr( offset ) + ' ' + IntToStr( seekOrigin ) );
  1459.   Result := S_OK;
  1460.   case SeekOrigin of
  1461.     soFromBeginning: arcPosition := Offset;
  1462.     soFromCurrent: arcPosition := arcPosition + Offset;
  1463.     soFromEnd: begin
  1464.       if arcSize > 0 then
  1465.         arcPosition := arcSize + Offset
  1466.       else Result := S_FALSE;
  1467.     end;
  1468.   end;
  1469.   if newPosition <> nil then newPosition^ := arcPosition;
  1470. end;
  1471. function TMyStreamReader.Read( var Data; Size: DWORD; ProcessedSize: PDWORD ): Integer; stdcall;
  1472. var
  1473.   fIdx: Integer;
  1474.   fPos, pSize, Read: DWORD;
  1475.   Buff: PChar;
  1476. begin
  1477.   //frmMain.mmoLog.Lines.Add( '-> Read ' + Format( '%.8x', [ Integer( data ) ] ) + ' ' + IntToStr( size ) );
  1478.   if FArchive then begin
  1479.     if ( Length( Files ) <= 1 ) and ( arcPosition + Size > Files[ 0 ].Size ) then begin
  1480.       arcSize := arcPosition + Size;
  1481.       if not OpenLastVolume then begin
  1482.         Result := S_FALSE;
  1483.         Exit;
  1484.       end else FMultivolume := TRUE;
  1485.     end;
  1486.   end;
  1487.   if ( not FArchive ) or ( not FMultivolume ) then begin
  1488.     FileSeek( Files[ 0 ].Handle, arcPosition, soFromBeginning );
  1489.     if not ReadFile( Files[ 0 ].Handle, Data, Size, pSize, nil ) then pSize := 0;
  1490.     Inc( arcPosition, pSize );
  1491.     if ProcessedSize <> nil then ProcessedSize^ := pSize;
  1492.     Result := S_OK;
  1493.     Exit;
  1494.   end;
  1495.   fIdx := -1;
  1496.   pSize := 0;
  1497.   repeat
  1498.     Inc( fIdx );
  1499.     if ( Files[ fIdx ].Handle < 0 ) and ( not OpenVolume( fIdx + 1 ) ) then begin
  1500.       Result := S_FALSE;
  1501.       Exit;
  1502.     end;
  1503.     pSize := pSize + Files[ fIdx ].Size;
  1504.   until arcPosition < pSize;
  1505.   Buff := @Data;
  1506.   fPos := arcPosition - ( pSize - Files[ fIdx ].Size );
  1507.   Read := 0;
  1508.   while Read < Size do begin
  1509.     if Read > 0 then begin
  1510.       with Files[ fIdx - 1 ] do begin
  1511.         FileClose( Handle );
  1512.         Handle := -1;
  1513.         Size := 0;
  1514.       end;
  1515.       if ( Files[ fIdx ].Handle < 0 ) and ( not OpenVolume( fIdx + 1 ) ) then begin
  1516.         Result := S_FALSE;
  1517.         Exit;
  1518.       end;
  1519.     end;
  1520.     FileSeek( Files[ fIdx ].Handle, fPos, soFromBeginning );
  1521.     pSize := Size - Read;
  1522.     if Files[ fIdx ].Size < fPos + pSize then pSize := Files[ fIdx ].Size - fPos;
  1523.     if not ReadFile( Files[ fIdx ].Handle, Buff[ Read ], pSize, pSize, nil ) then begin
  1524.       Read := 0;
  1525.       Break;
  1526.     end;
  1527.     Inc( Read, pSize );
  1528.     Inc( fIdx );
  1529.     fPos := 0;
  1530.   end;
  1531.   Inc( arcPosition, Read );
  1532.   if Assigned( ProcessedSize ) then ProcessedSize^ := Read;
  1533.   Result := S_OK;
  1534. end;
  1535. function TMyStreamReader.ReadPart( var data; size: DWORD; processedSize: PDWORD ): Integer; stdcall;
  1536. begin
  1537.   //frmMain.mmoLog.Lines.Add( '-> ReadPart ' + IntToStr( size ) );
  1538.   Result := Read( Data, Size, ProcessedSize );
  1539. end;
  1540. function TMyStreamReader.GetSize( var size: Int64 ): Integer; stdcall;
  1541. begin
  1542.   //frmMain.mmoLog.Lines.Add( 'GetSize' );
  1543.   if arcSize > 0 then begin
  1544.     Size := arcSize;
  1545.     Result := S_OK;
  1546.   end else Result := S_FALSE;
  1547. end;
  1548. function TMyStreamReader.BrowseForFile( Title: PWideChar; var Name: WideString ): Boolean;
  1549. var
  1550.   OpenFileName: TOpenFilenameW;
  1551.   FileName: array[ 0..MAX_PATH - 1 ] of WideChar;
  1552.   s: WideString;
  1553. begin
  1554.   Result := FALSE;
  1555.   try
  1556.     s := ExtractFileNameW( Name );
  1557.     s := Copy( s, 1, Length( s ) - Length( ExtractFileExtW( Name ) ) );
  1558.     s := s + '-volumes'#0 + s + '.*'#0;
  1559.     FillChar( FileName, MAX_PATH, 0 );
  1560.     FillChar( OpenFileName, SizeOf( OpenFileName ), 0 );
  1561.     OpenFileName.lStructSize := SizeOf( OpenFileName );
  1562.     OpenFileName.hWndOwner := Application.Handle;
  1563.     OpenFileName.lpstrInitialDir := PWideChar( ExtractFilePathW( Name ) );
  1564.     OpenFileName.lpstrFile := @FileName;
  1565.     OpenFileName.nMaxFile := MAX_PATH;
  1566.     OpenFileName.lpstrFilter := @s[ 1 ];
  1567.     OpenFileName.nFilterIndex := 1;
  1568.     OpenFileName.Flags := OFN_PATHMUSTEXIST Or OFN_FILEMUSTEXIST;
  1569.     if GetOpenFileNameW( OpenFileName ) then begin
  1570.       Name := FileName;
  1571.       Result := ( GetLastError = 0 );
  1572.     end else Result := FALSE;
  1573.   except
  1574.   end;
  1575. end;
  1576. function TMyStreamReader.OpenVolume( Index: Integer ): Boolean;
  1577. var
  1578.   i: Integer;
  1579.   s: WideString;
  1580.   fCancel: Boolean;
  1581. begin
  1582.   Result := FALSE;
  1583.   if Index <= 0 then
  1584.     Exit
  1585.   else if Index <= Length( Files ) then begin
  1586.     if Files[ Index - 1 ].Handle > 0 then begin
  1587.       Result := TRUE;
  1588.       Exit;
  1589.     end;
  1590.   end else begin
  1591.     i := Length( Files );
  1592.     while i < Index do begin
  1593.       SetLength( Files, i + 1 );
  1594.       Files[ i ].Handle := -1;
  1595.       Files[ i ].Size := 0;
  1596.       Inc( i );
  1597.     end;
  1598.   end;
  1599.   Dec( Index );
  1600.   if Length( Files[ Index ].Name ) <= 0 then begin
  1601.     s := IntToStr( Index + 1 );
  1602.     while Length( s ) < 3 do s := '0' + s;
  1603. // Shadow 28.11.2006
  1604.     if Assigned( FSevenZip ) and FSevenZip.IsSFX then begin
  1605.       Files[ Index ].Name := arcName + '.' + s
  1606.     end else Files[ Index ].Name := Copy( arcName, 1, Length( arcName ) - Length( ExtractFileExtW( arcName ) ) ) + '.' + s;
  1607.   end;
  1608.   while Files[ Index ].Handle <= 0 do begin
  1609.     Files[ Index ].Handle := CreateFile_( PwideChar( Files[ Index ].Name ), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0 );
  1610.     if Files[ Index ].Handle <= 0 then begin
  1611.       if Assigned( FOnOpenVolume ) then begin
  1612.         FOnOpenVolume( Files[ Index ].Name, Files[ Index ].OnRemovableDrive, fCancel );
  1613.         if not fCancel then Continue;
  1614.       end else begin
  1615.         if BrowseForFile( 'Select volume', Files[ Index ].Name ) then Continue;
  1616.       end;
  1617.       Files[ Index ].Name := '';
  1618.       Result := FALSE;
  1619.       Exit;
  1620.     end;
  1621.     Files[ Index ].Size := FileSeek( Files[ Index ].Handle, 0, soFromEnd );
  1622.     FileSeek( Files[ Index ].Handle, 0, soFromBeginning );
  1623.   end;
  1624.   Result := ( Files[ Index ].Size > 0 );
  1625. end;
  1626. function TMyStreamReader.OpenNextVolume: Boolean;
  1627. begin
  1628.   Result := OpenVolume( Length( Files ) + 1 );
  1629. end;
  1630. function TMyStreamReader.OpenLastVolume: Boolean;
  1631. var
  1632.   Name: WideString;
  1633.   n: Integer;
  1634.   function GetLastVolumeFN(first:widestring):widestring;
  1635.   var n:integer;
  1636.       s,e,lastfound:widestring;
  1637.   begin
  1638.     Result := '';
  1639.     s:= ChangeFileExtW( first,'');
  1640.     lastfound := first;
  1641.     if not TryStrToInt_( Copy( ExtractFileExtW( first ), 2, MaxInt ), n) then exit;
  1642.     e:= '00' + inttostr(n);
  1643.     repeat
  1644.       lastfound := s + '.' + e;
  1645.       inc(n);
  1646.       e:= inttostr(n);
  1647.       while Length( e ) < 3 do e := '0' + e;
  1648.     until not fileexists_( s + '.' + e);
  1649.     Result := lastfound;
  1650.   end;
  1651. begin
  1652.   Result := FALSE;
  1653.   repeat
  1654. {
  1655.     if Assigned( FOnOpenVolume ) then begin
  1656.       Name := ChangeFileExtW( Files[ 0 ].Name, '.*' );
  1657.       FOnOpenVolume( Name, Files[ 0 ].OnRemovableDrive, Result );
  1658.       if Result then begin
  1659.         Result := FALSE;
  1660.         Exit;
  1661.       end;
  1662.     end else begin
  1663.       Name := arcName;
  1664.       if not BrowseForFile( 'Select last volume', Name ) then Exit;
  1665.     end;
  1666. }
  1667.    name := '';
  1668.    name := GetLastVolumeFN(Arcname);
  1669.    if name = '' then
  1670.     if not BrowseForFile( 'Select last volume', Name ) then Exit;
  1671. // Shadow 28.11.2006
  1672.     if Assigned( FSevenZip ) and FSevenZip.IsSFX then begin
  1673.       if UpperCaseW_( ChangeFileExtW( ExtractFileNameW( Name ), '' ) ) <>
  1674.          UpperCaseW_( ExtractFileNameW( Files[ 0 ].Name ) ) then Continue;
  1675.     end else begin
  1676.       if UpperCaseW_( ChangeFileExtW( ExtractFileNameW( Name ), ExtractFileExtW( Files[ 0 ].Name ) ) ) <>
  1677.          UpperCaseW_( ExtractFileNameW( Files[ 0 ].Name ) ) then Continue;
  1678.     end;
  1679.     if not TryStrToInt_( Copy( ExtractFileExtW( Name ), 2, MaxInt ), n ) then Continue;
  1680.   until n > 1;
  1681.   Result := OpenVolume( n );
  1682. end;
  1683. constructor TMyStreamReader.Create( Owner: TSevenZip; sz: Widestring; asArchive: Boolean );
  1684. begin
  1685.   inherited Create;
  1686.   arcName := sz;
  1687.   arcPosition := 0;
  1688.   FSevenZip := Owner;
  1689.   if Assigned( FSevenZip ) then begin
  1690.     if Owner.IsSFX then arcPosition := Owner.SFXOffset;
  1691.     FOnOpenVolume := FSevenZip.FOnOpenVolume;
  1692.   end else FOnOpenVolume := nil;
  1693.   FArchive := asArchive;
  1694.   FMultivolume := FALSE;
  1695.   SetLength( Files, 1 );
  1696.   Files[ 0 ].Name := arcName;
  1697.   Files[ 0 ].Handle := CreateFile_( PWideChar( Files[ 0 ].Name ), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0 );
  1698.   Files[ 0 ].Size := FileSeek( Files[ 0 ].Handle, 0, soFromEnd );
  1699.   Files[ 0 ].OnRemovableDrive := DriveIsRemovable( Copy( ExtractFilePathW( Files[ 0 ].Name ), 1, 2 ) );
  1700.   if not FArchive then
  1701.     arcSize := Files[ 0 ].Size
  1702.   else arcSize := 0;
  1703. //  frmMain.mmoLog.Lines.Add( IntToStr( fIn ) );
  1704. end;
  1705. destructor TMyStreamReader.Destroy;
  1706. var
  1707.   i: Integer;
  1708. begin
  1709.   for i := 0 to Length( Files ) - 1 do if Files[ i ].Handle > 0 then FileClose( Files[ i ].Handle );
  1710.   SetLength( Files, 0 );
  1711.   Log( 'TMyStreamReader.Destroy' );
  1712.   inherited;
  1713. end;
  1714. {============ TMyStreamWriter =================================================}
  1715. function TMyStreamWriter.Write( const Data; Size: DWORD; ProcessedSize: PDWORD ): Integer; stdcall;
  1716. var
  1717.   fIdx: Integer;
  1718.   fPos, pSize, Written: DWORD;
  1719.   Buff: PChar;
  1720. begin
  1721.   Log( Format( '-> Write( %.8x, %d )', [ Integer( data ), size ] ) );
  1722.   if arcVolumeSize > 0 then begin
  1723.     fIdx := ( arcPosition + Size ) div arcVolumeSize;
  1724.     while Length( Files ) < Integer( Succ( fIdx ) ) do CreateNewFile;
  1725.     fIdx := arcPosition div arcVolumeSize;
  1726.     fPos := arcPosition mod arcVolumeSize;
  1727.     Buff := @Data;
  1728.     Written := 0;
  1729.     while Written < Size do begin
  1730.       FileSeek( Files[ fIdx ].Handle, fPos, soFromBeginning );
  1731.       pSize := Size - Written;
  1732.       if arcVolumeSize < fPos + pSize then pSize := arcVolumeSize - fPos;
  1733.       if not WriteFile( Files[ fIdx ].Handle, Buff[ Written ], pSize, pSize, nil ) then begin
  1734.         Written := 0;
  1735.         Break;
  1736.       end;
  1737.       Inc( Written, pSize );
  1738.       Inc( fIdx );
  1739.       fPos := 0;
  1740.     end;
  1741.   end else begin
  1742.     FileSeek( Files[ 0 ].Handle, arcPosition, soFromBeginning );
  1743.     if not WriteFile( Files[ 0 ].Handle, Data, Size, Written, nil ) then Written := 0;
  1744.   end;
  1745.   Inc( arcPosition, Written );
  1746.   if arcPosition > arcSize then arcSize := arcPosition;
  1747.   if Assigned( ProcessedSize ) then ProcessedSize^ := Written;
  1748.   Result := S_OK;
  1749. end;
  1750. function TMyStreamWriter.WritePart( const Data; Size: DWORD; ProcessedSize: PDWORD ): Integer; stdcall;
  1751. begin
  1752.   Result := Write( Data, Size, ProcessedSize );
  1753. end;
  1754. function TMyStreamWriter.Seek( Offset: Int64; SeekOrigin: DWORD; NewPosition: PInt64 ): Integer; stdcall;
  1755. begin
  1756.   Log( Format( 'TMyStreamWriter.Seek( %d, %d, %.8x )', [ offset, seekOrigin, Integer( newPosition ) ] ) );
  1757.   case SeekOrigin of
  1758.     soFromBeginning: arcPosition := Offset;
  1759.     soFromCurrent: arcPosition := arcPosition + Offset;
  1760.     soFromEnd: arcPosition := arcSize + Offset;
  1761.   end;
  1762.   if arcPosition > arcSize then arcSize := arcPosition;
  1763.   if newPosition <> nil then newPosition^ := arcPosition;
  1764.   Result := S_OK;
  1765. end;
  1766. function TMyStreamWriter.SetSize( newSize: Int64 ): Integer; stdcall;
  1767. begin
  1768.   Log( Format( 'TMyStreamWriter.SetSize( %d )', [ newSize ] ) );
  1769.   Result := S_FALSE;
  1770. end;
  1771. destructor TMyStreamWriter.Destroy;
  1772. var
  1773.   i: Integer;
  1774. begin
  1775.   for i := Low( Files ) to High( Files ) do FileClose( Files[ i ].Handle );
  1776.   Log( 'TMyStreamWriter.Destroy' );
  1777.   inherited;
  1778. end;
  1779. function TMyStreamWriter.CreateNewFile: Boolean;
  1780. var
  1781.   i: Integer;
  1782.   s: WideString;
  1783. begin
  1784.   i := Length( Files );
  1785.   SetLength( Files, i + 1 );
  1786.   if arcVolumeSize > 0 then begin
  1787.     s := IntToStr( i + 1 );
  1788.     while Length( s ) < 3 do s := '0' + s;
  1789.     s := arcName + '.' + s;
  1790.   end else s := arcName;
  1791.   if arcCreateSFX and ( i = 0 ) then begin
  1792. // Shadow 27.11.2006
  1793.     Files[ 0 ].Handle := CreateFile_( PwideChar( arcName ), GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, arcAttr, 0 );
  1794.     if Files[ 0 ].Handle > 0 then arcPosition := FileSeek( Files[ 0 ].Handle, 0, soFromEnd );
  1795.   end else
  1796.     Files[ i ].Handle := CreateFile_( PwideChar( s ), GENERIC_READ or GENERIC_WRITE, 0, nil, CREATE_ALWAYS, arcAttr, 0 );
  1797.   if Files[ i ].Handle <= 0 then Abort;
  1798.   FileSetDate( Files[ i ].Handle, DateTimeToFileDate( arcDate ) );
  1799.   Result := TRUE;
  1800. end;
  1801. constructor TMyStreamWriter.Create( sz: Widestring; szDate: Tdatetime; FAttr: Cardinal; VolumeSize: Integer; CreateSFX: Boolean );
  1802. begin
  1803.   inherited Create;
  1804.   arcName := sz;
  1805.   arcDate := szDate;
  1806.   arcAttr := FAttr;
  1807.   arcCreateSFX := CreateSFX;
  1808.   arcVolumeSize := VolumeSize;
  1809.   arcPosition := 0;
  1810.   arcSize := 0;
  1811.   SetLength( Files, 0 );
  1812.   if not CreateNewFile then Abort;
  1813. end;
  1814. // ------------------------------------------------------------------------------------------
  1815. //functions for SevenZip
  1816. function PropIDToString( propID: Integer ): string;
  1817. begin
  1818.   case propID of
  1819.     kpidNoProperty       : Result := 'kpidNoProperty';
  1820.     kpidHandlerItemIndex : Result := 'kpidHandlerItemIndex';
  1821.     kpidPath             : Result := 'kpidPath';
  1822.     kpidName             : Result := 'kpidName';
  1823.     kpidExtension        : Result := 'kpidExtension';
  1824.     kpidIsFolder         : Result := 'kpidIsFolder';
  1825.     kpidSize             : Result := 'kpidSize';
  1826.     kpidPackedSize       : Result := 'kpidPackedSize';
  1827.     kpidAttributes       : Result := 'kpidAttributes';
  1828.     kpidCreationTime     : Result := 'kpidCreationTime';
  1829.     kpidLastAccessTime   : Result := 'kpidLastAccessTime';
  1830.     kpidLastWriteTime    : Result := 'kpidLastWriteTime';
  1831.     kpidSolid            : Result := 'kpidSolid';
  1832.     kpidCommented        : Result := 'kpidCommented';
  1833.     kpidEncrypted        : Result := 'kpidEncrypted';
  1834.     kpidSplitBefore      : Result := 'kpidSplitBefore';
  1835.     kpidSplitAfter       : Result := 'kpidSplitAfter';
  1836.     kpidDictionarySize   : Result := 'kpidDictionarySize';
  1837.     kpidCRC              : Result := 'kpidCRC';
  1838.     kpidType             : Result := 'kpidType';
  1839.     kpidIsAnti           : Result := 'kpidIsAnti';
  1840.     kpidMethod           : Result := 'kpidMethod';
  1841.     kpidHostOS           : Result := 'kpidHostOS';
  1842.     kpidFileSystem       : Result := 'kpidFileSystem';
  1843.     kpidUser             : Result := 'kpidUser';
  1844.     kpidGroup            : Result := 'kpidGroup';
  1845.     kpidBlock            : Result := 'kpidBlock';
  1846.     kpidComment          : Result := 'kpidComment';
  1847.     kpidPosition         : Result := 'kpidPosition';
  1848.     kpidTotalSize        : Result := 'kpidTotalSize';
  1849.     kpidFreeSpace        : Result := 'kpidFreeSpace';
  1850.     kpidClusterSize      : Result := 'kpidClusterSize';
  1851.     kpidVolumeName       : Result := 'kpidVolumeName';
  1852.     kpidLocalName        : Result := 'kpidLocalName';
  1853.     kpidProvider         : Result := 'kpidProvider';
  1854.     kpidUserDefined      : Result := 'kpidUserDefined';
  1855.   else
  1856.     Result := 'unknown';
  1857.   end;
  1858. end;
  1859. function PropTypeToString( propType: Integer ): string;
  1860. begin
  1861.   case propType of
  1862.     VT_EMPTY          : Result := 'VT_EMPTY';
  1863.     VT_NULL           : Result := 'VT_NULL';
  1864.     VT_I2             : Result := 'VT_I2';
  1865.     VT_I4             : Result := 'VT_I4';
  1866.     VT_R4             : Result := 'VT_R4';
  1867.     VT_R8             : Result := 'VT_R8';
  1868.     VT_CY             : Result := 'VT_CY';
  1869.     VT_DATE           : Result := 'VT_DATE';
  1870.     VT_BSTR           : Result := 'VT_BSTR';
  1871.     VT_DISPATCH       : Result := 'VT_DISPATCH';
  1872.     VT_ERROR          : Result := 'VT_ERROR';
  1873.     VT_BOOL           : Result := 'VT_BOOL';
  1874.     VT_VARIANT        : Result := 'VT_VARIANT';
  1875.     VT_UNKNOWN        : Result := 'VT_UNKNOWN';
  1876.     VT_DECIMAL        : Result := 'VT_DECIMAL';
  1877.     VT_I1             : Result := 'VT_I1';
  1878.     VT_UI1            : Result := 'VT_UI1';
  1879.     VT_UI2            : Result := 'VT_UI2';
  1880.     VT_UI4            : Result := 'VT_UI4';
  1881.     VT_I8             : Result := 'VT_I8';
  1882.     VT_UI8            : Result := 'VT_UI8';
  1883.     VT_INT            : Result := 'VT_INT';
  1884.     VT_UINT           : Result := 'VT_UINT';
  1885.     VT_VOID           : Result := 'VT_VOID';
  1886.     VT_HRESULT        : Result := 'VT_HRESULT';
  1887.     VT_PTR            : Result := 'VT_PTR';
  1888.     VT_SAFEARRAY      : Result := 'VT_SAFEARRAY';
  1889.     VT_CARRAY         : Result := 'VT_CARRAY';
  1890.     VT_USERDEFINED    : Result := 'VT_USERDEFINED';
  1891.     VT_LPSTR          : Result := 'VT_LPSTR';
  1892.     VT_LPWSTR         : Result := 'VT_LPWSTR';
  1893.     VT_FILETIME       : Result := 'VT_FILETIME';
  1894.     VT_BLOB           : Result := 'VT_BLOB';
  1895.     VT_STREAM         : Result := 'VT_STREAM';
  1896.     VT_STORAGE        : Result := 'VT_STORAGE';
  1897.     VT_STREAMED_OBJECT: Result := 'VT_STREAMED_OBJECT';
  1898.     VT_STORED_OBJECT  : Result := 'VT_STORED_OBJECT';
  1899.     VT_BLOB_OBJECT    : Result := 'VT_BLOB_OBJECT';
  1900.     VT_CF             : Result := 'VT_CF';
  1901.     VT_CLSID          : Result := 'VT_CLSID';
  1902.   else
  1903.     Result := 'Unknown';
  1904.   end;
  1905. end;
  1906. //--------------------------------------------------------------------------------------------------
  1907. //--------------------------------------------------------------------------------------------------
  1908. //-------------------End SevenZip Interface -------------------------------------------------
  1909. //--------------------------------------------------------------------------------------------------
  1910. //--------------------------------------------------------------------------------------------------
  1911. //--------------------------------------------------------------------------------------------------
  1912. //-----------------START DEBUG ONLY-----------------------------------------------------------------
  1913. //--------------------------------------------------------------------------------------------------
  1914. // For Debug only
  1915. // Add this to your MainForm public
  1916. {
  1917.  procedure LogMessage( var msg: TMessage ); message 9999;
  1918. }
  1919. {
  1920.   procedure TForm1.SevenZip1Message( Sender: TObject; ErrCode: Integer; Message: String );
  1921.   begin
  1922.    memo1.lines.add( message );
  1923.   end;
  1924. }
  1925. // and to Form.Activate this ( or set it when you want with e.g. a Button )
  1926. {
  1927.  sevenzipvcl.FMainhandle := form1.Handle;
  1928. }
  1929. procedure Log( sz: string );
  1930. var
  1931.   p: PString;
  1932. begin
  1933.   p := new( PString );
  1934.   p^ := sz;
  1935.   PostMessage( fMainhandle, 9999, 0, Integer( p ) );
  1936. end;
  1937. //--------------------------------------------------------------------------------------------------
  1938. //-----------------END DEBUG ONLY-------------------------------------------------------------------
  1939. //--------------------------------------------------------------------------------------------------
  1940. //------------------------------------------------------------------------------------------------
  1941. //------------------------------------------------------------------------------------------------
  1942. //-----------------Start SevenZip VCL-------------------------------------------------------
  1943. //------------------------------------------------------------------------------------------------
  1944. //------------------------------------------------------------------------------------------------
  1945. //constructor destructor
  1946. //------------------------------------------------------------------------------------------------
  1947. (*
  1948. procedure TSevenZip.LogMessage( var msg: TMessage );
  1949. begin
  1950.   if assigned( onMessage ) then OnMessage( Self,0,PString( msg.LParam )^ );
  1951.   Dispose( PString( msg.LParam ) );
  1952. end;
  1953. *)
  1954. constructor TSevenZip.Create( AOwner: TComponent );
  1955. var OSVerInfo : TOSVersionInfo;
  1956. {$IFDEF UseRes7zdll}
  1957.   MemoryStream: TResourceStream;
  1958. {$ENDIF}
  1959. begin
  1960.   inherited Create( AOwner );
  1961.   ffiles := TWideStringList_.Create;
  1962.   ResetCancel;
  1963.   FMainHandle := FHandle;
  1964.   FNumberOfFiles := -1;
  1965.   FPassword := '';
  1966.   FSFXModule := '7z.sfx';
  1967. // Shadow 28.11.2006
  1968.   FCreateObject := nil;
  1969.   F7zaLibh := LoadLibrary( '7za.dll' );
  1970. {$IFDEF Use7zdll}
  1971.   if F7zaLibh > 0 then
  1972.     @FCreateObject := GetProcAddress( F7zaLibh, 'CreateObject' );
  1973. {$ENDIF}
  1974. {$IFDEF UseRes7zdll}
  1975.     MemoryStream := TResourceStream.Create( HInstance, '7zip_library', RT_RCDATA );
  1976.     try
  1977.       m_DllDataSize := MemoryStream.Size;
  1978.       mp_DllData := GetMemory( m_DllDataSize );
  1979.       MemoryStream.Read( mp_DllData^, m_DllDataSize );
  1980.     finally
  1981.       MemoryStream.Free;
  1982.     end;
  1983.     mp_MemoryModule := BTMemoryLoadLibary( mp_DllData, m_DllDataSize );
  1984.     @FCreateObject := BTMemoryGetProcAddress( mp_MemoryModule, 'CreateObject' );
  1985. {$ENDIF}
  1986.   if not Assigned( FCreateObject ) then begin
  1987.     raise Exception.Create( 'Could not load CreateObject function from 7za.dll' + #13#10 + 'Perhaps 7za.dll not found' );
  1988.   end else begin
  1989.     FCreateObject( @CLSID_CFormat7z, @IID_IInArchive, inA );
  1990.     FCreateObject( @CLSID_CFormat7z, @IID_IOutArchive, outA );
  1991.     FCreateObject( @CLSID_CFormat7z, @IID_ISetProperties, sp );
  1992.   end;
  1993.   OSVerInfo.dwOSVersionInfoSize := sizeof(OSVerInfo);
  1994.   GetVersionEx(OsVerInfo);
  1995.   if osverinfo.dwPlatformID = VER_PLATFORM_WIN32_WINDOWS then
  1996.    isUnicode := false
  1997.   else
  1998.    isUnicode := true;
  1999. end;
  2000. destructor TSevenzip.Destroy;
  2001. begin
  2002. //jjw 18.10.2006
  2003.   inA := nil;
  2004.   outA := nil;
  2005.   sp := nil;
  2006.   if F7zaLibh > 0 then FreeLibrary( F7zaLibh );
  2007. {$IFDEF UseRes7zdll}
  2008.   if m_DllDataSize > 0 then FreeMemory( mp_DllData );
  2009.   if mp_MemoryModule <> nil then BTMemoryFreeLibrary( mp_MemoryModule );
  2010. {$ENDIF}
  2011.   
  2012.   ffiles.Clear;
  2013.   ffiles.Free;
  2014.   inherited;
  2015. end;
  2016. //------------------------------------------------------------------------------------------------
  2017. //End constructor destructor
  2018. //------------------------------------------------------------------------------------------------
  2019. Procedure TSevenZip.Cancel; // public
  2020. begin
  2021.  FMainCancel := True;
  2022. end;
  2023. Procedure TSevenZip.ResetCancel; // private
  2024. begin
  2025.  FMainCancel := False;
  2026. end;
  2027. //RG 02.06.2006
  2028. function TSevenZip.GetIndexByFilename( FileToExtract: Widestring ): Integer;
  2029. var
  2030.   n: Integer;
  2031.   w: DWORD;
  2032.   fnameprop: PROPVARIANT;
  2033.   fileInArchive: widestring;
  2034.   ms: TMyStreamReader;
  2035. begin
  2036.   try
  2037.     Result := -1;
  2038.     ms := TMyStreamReader.Create( Self, FSevenZipFileName, TRUE );
  2039.     inA.Close;
  2040.     inA.Open( ms, nil, nil );
  2041.     inA.GetNumberOfItems( w ); //1..end
  2042.     FileToExtract := UppercaseW_( FileToExtract );
  2043.     for n := 0 to w-1 do begin
  2044.       fnameprop.vt := VT_EMPTY;
  2045.       inA.GetProperty( n, kpidPath, fnameprop );
  2046.       fileInArchive := UppercaseW_( OleStrToString( fnameprop.bstrVal ) );
  2047.       if ( fileInArchive = FileToExtract ) then begin
  2048.         Result := n;
  2049.         Break;
  2050.       end;
  2051.     end;
  2052.   finally
  2053.     inA.close;
  2054.   end
  2055. end;
  2056. //-------------------------------------------------------
  2057. //SFX functions
  2058. // Shadow 28.11.2006
  2059. function TSevenZip.SFXCheck( Fn: WideString ): Boolean;
  2060. const
  2061.   ID_7z: Array[ 0..5 ] of byte = ( 55, 122, 188, 175, 39, 28 );
  2062. var
  2063.   MySize, MyOrigSize: DWORD;
  2064.   Source: Integer;
  2065.   Buffer: array[ 0..81919 ] of Byte;
  2066.   ReadBytes, i: DWORD;
  2067.   function MyOriginalSize: DWORD;
  2068.   var
  2069.     s, d: DWORD;
  2070.     w: Word;
  2071.   begin
  2072.     Result := 0;
  2073.     s := FileSeek( Source, 0, soFromCurrent );
  2074.     try
  2075.       FileSeek( Source, $3C, soFromBeginning );
  2076.       FileRead( Source, d, 4 );
  2077.       FileSeek( Source, d + $06, soFromBeginning );
  2078.       FileRead( Source, w, 2 );
  2079. {?????????????}
  2080.       Inc( w );
  2081. {?????????????}
  2082.       FileSeek( Source, ( d + $F8 ) + ( w * $28 ) - $14 , soFromBeginning );
  2083.       FileRead( Source, Result, 4 );
  2084.     finally
  2085.       FileSeek( Source, s, soFromBeginning );
  2086.     end;
  2087.   end;
  2088.   function CheckSignature( Offset: Integer ): Boolean;
  2089.   var
  2090.     i: Integer;
  2091.   begin
  2092.     Result := FALSE;
  2093.     for i := 0 to 5 do begin
  2094.       if ( Buffer[ Offset + i ] <> ID_7z[ i ] ) then Break;
  2095.       if i = 5 then Result := TRUE;
  2096.     end;
  2097.   end;
  2098. begin
  2099.   Result := FALSE;
  2100.   if UpperCaseW_( ExtractFileExtW( Fn ) ) <> '.EXE' then Exit;
  2101.   FSFXoffset := 0;
  2102.   FIsSFX := FALSE;
  2103.   Source := CreateFile_( PWideChar( Fn ), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0 );
  2104.   try
  2105.     MySize := FileSeek( Source, 0, soFromEnd );
  2106.     FileSeek( Source, 65536, soFromBeginning );
  2107.     ReadFile( Source, Buffer[ 0 ], SizeOf( Buffer ), ReadBytes, nil );
  2108.     for i := 0 to ReadBytes - 6 do begin
  2109.       FIsSFX := CheckSignature( i );
  2110.       if FIsSFX then begin
  2111.         FSFXOffset := 65536 + i;
  2112.         Result := TRUE;
  2113.         Break;
  2114.       end;
  2115.     end;
  2116.     if not FIsSFX then begin
  2117.       MyOrigSize := MyOriginalSize;
  2118.       if MySize <> MyOrigSize then begin
  2119.         FileSeek( Source, MyOrigSize, soFromBeginning );
  2120.         ReadFile( Source, Buffer[ 0 ], 6, ReadBytes, nil );
  2121.         FIsSFX := CheckSignature( 0 );
  2122.         if FIsSFX then begin
  2123.           FSFXOffset := MyOrigSize;
  2124.           Result := TRUE;
  2125.         end;
  2126.       end;
  2127.     end;
  2128.   finally
  2129.     FileClose( Source );
  2130.   end;
  2131. end;
  2132. function TSevenZip.ConvertSFXto7z( Fn:Widestring ): boolean;
  2133. var Source,Dest: Integer;
  2134.     DestFn: Widestring;
  2135.     buffer: pointer;
  2136.     readbytes,writebytes:Dword;
  2137. const
  2138.     chunksize = 1024*128;
  2139. begin
  2140.   //ErikGG Begin 08.11.06
  2141.   Buffer := Nil;
  2142.   Source := -1;
  2143.   Dest := -1;
  2144.   // Lifepower (07-Jan-2007):
  2145.   //  Commented unused value assignment.
  2146.   //Result := False;
  2147.   //ErikGG End 08.11.06
  2148.   try
  2149.     DestFn := changefileextW( Fn,'.7z' );
  2150.      Source := CreateFile_( PwideChar( Fn ), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0 );
  2151.     Fileseek( Source,SFXoffset,0 ); //goto 7z data
  2152.     Dest := CreateFile_( PwideChar( DestFn ), GENERIC_WRITE, 0, nil, CREATE_ALWAYS, 0, 0 );
  2153.     GetMem( Buffer,chunksize ); { allocate the buffer }
  2154.     repeat
  2155.       readbytes := Fileread( Source,buffer^,chunksize );
  2156.       writebytes := Filewrite( Dest,buffer^,readbytes );
  2157.     until readbytes < chunksize;
  2158.     if writebytes = 0 then;
  2159.     //ErikGG 08.11.06
  2160.     Result := true;//Only reached if no error happend
  2161.   finally
  2162.     //ErikGG Begin 07.11.06
  2163.     if Buffer <> Nil then freemem( buffer );
  2164.     if Source <> 0 then   Fileclose( Source );
  2165.     if Dest <> 0 then     Fileclose( Dest );
  2166.     //ErikGG End 07.11.06
  2167.   end;
  2168. end;
  2169. function TSevenZip.Convert7ztoSFX( Fn:Widestring ): boolean;
  2170. var Source,Dest: Integer;
  2171.     DestFn: Widestring;
  2172.     buffer: pointer;
  2173.     readbytes,writebytes:Dword;
  2174. const
  2175.     chunksize = 1024*128;
  2176. begin
  2177.  //ErikGG Begin 07.11.06
  2178.  Result := false;
  2179.  Buffer := Nil;
  2180.  Source := -1;
  2181.  Dest := -1;
  2182.  //ErikGG End 07.11.06
  2183.  DestFn := changefileextW( Fn,'.exe' );
  2184.  if not copyfilew( PWidechar( sfxmodule ),PWideChar( DestFn ),True ) then
  2185.   begin
  2186.    if assigned( onMessage ) then onMessage( self,8,'SFXModule error ( Not found )',Fsevenzipfilename );
  2187.    exit;
  2188.   end;
  2189. try
  2190.   Source := CreateFile_( PwideChar( Fn ), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0 );
  2191.   Dest := CreateFile_( PwideChar( DestFn ), GENERIC_Write, 0, nil, OPEN_EXISTING, 0, 0 );
  2192.   fileseek( Dest,0,2 );
  2193.   GetMem( Buffer,chunksize ); { allocate the buffer }
  2194.   repeat
  2195.     readbytes := Fileread( Source,buffer^,chunksize );
  2196.     writebytes := Filewrite( Dest,buffer^,readbytes );
  2197.   until readbytes < chunksize;
  2198.   if writebytes = 0 then;
  2199.   //ErikGG 07.11.06
  2200.   Result := true;//Only reached if no error happend
  2201. finally
  2202.  if Buffer <> Nil then freemem( buffer );
  2203.  if Source <> 0 then   Fileclose( Source );
  2204.  if Dest <> 0 then     Fileclose( Dest );
  2205.  //ErikGG End 07.11.06
  2206. end;
  2207. end;
  2208. //SFX functions end
  2209. //-------------------------------------------------------
  2210. function TSevenZip.List: Integer;
  2211. var
  2212.   ms: TMyStreamReader;
  2213.   updateOpenCallback: TmyArchiveOpenCallback;
  2214.   i: Integer;
  2215.   w: DWord;
  2216.   name: TBSTR;
  2217.   prop: PROPID;
  2218.   pType: Integer;
  2219.   path: PROPVARIANT;
  2220.   size: PROPVARIANT;
  2221.   packedsize: PROPVARIANT;
  2222.   attr:PROPVARIANT;
  2223.   fcrc: PROPVARIANT;
  2224.   szMethod: PROPVARIANT;
  2225.   sztime: PROPVARIANT;
  2226.   szMethod_WS: Widestring;
  2227.   blockpid: PROPVARIANT;
  2228. begin
  2229.   try
  2230.     Ffiles.Clear;
  2231.     FNumberOfFiles := -1;
  2232.     if UppercaseW_( ExtractFileExtW( FSevenZipFileName ) ) = '.EXE' then begin
  2233.       if not SFXCheck( FSevenZipFileName ) then begin
  2234.         Result := -1;
  2235.         if assigned( onMessage ) then onMessage( self,7,'File is not an 7z SFX archive',Fsevenzipfilename );
  2236.         Exit;
  2237.       end;
  2238.     end;
  2239.     ms := TMyStreamReader.Create( Self, FSevenZipFileName, TRUE );
  2240.     inA.Close;
  2241. // 24.08.06 - Matteo Riso - Status: experimental
  2242. // 25.08.06 Modified by rg
  2243. //
  2244. // If we loaded an .EXE file, we could start reading from offset 132096.
  2245. // Also supported by newerdll
  2246. //  if FIsSFX then ms.Seek( FSFXOffset,0,@FSFXOffset );
  2247. // End - MR modification
  2248.     updateOpenCallback := TMyArchiveOpenCallback.Create( self );
  2249.     i := inA.Open(ms, nil,updateOpencallback );
  2250.   if i <> 0 then
  2251.    begin
  2252.      Result := -1;
  2253.      if assigned( onMessage ) then onMessage( self,1,'File not found',Fsevenzipfilename );
  2254.      Exit;
  2255.    end;
  2256. (*
  2257.    inA.GetNumberOfArchiveProperties( w );
  2258.    for i := 0 to w-1 do
  2259.     begin
  2260.      path.vt := VT_EMPTY;
  2261.      ina.GetArchiveProperty( kpidPath,@path );
  2262.      if assigned( onMessage ) then onMessage( self,i,path.bstrVal,path.pwszVal );
  2263.     end;
  2264. *)
  2265.   inA.GetNumberOfProperties( w );
  2266.   for i := 0 to w - 1 do
  2267.   begin
  2268.     name := new( TBSTR );
  2269.     ptype := 0;
  2270.     inA.GetPropertyInfo( i, name, prop, pType );
  2271.     if name = nil then
  2272.     begin
  2273.       Log( Format( '%d %s %s ( %d ) %s ( %d )', [ i, '', PropIDToString( prop ), prop, PropTypeToString( pType ), pType ] ) )
  2274.     end else
  2275.     begin
  2276.       log( Format( '%d %s %s ( %d ) %s ( %d )', [ i, name, PropIDToString( prop ), prop, PropTypeToString( pType ), pType ] ) );
  2277.     end;
  2278.   end;
  2279.   inA.GetNumberOfItems( w );
  2280.   FNumberOfFiles := w;
  2281.   for i := 0 to w-1 do
  2282.    begin
  2283.        path.vt := VT_EMPTY;
  2284.        size.vt := VT_EMPTY;
  2285.        packedsize.vt := VT_EMPTY;
  2286.        attr.vt := VT_EMPTY;
  2287.        fcrc.vt := VT_EMPTY;
  2288.        szmethod.vt := VT_EMPTY;
  2289.        sztime.vt := VT_EMPTY;
  2290.        blockpid.vt := VT_EMPTY;
  2291.        inA.GetProperty( i, kpidPath, path );
  2292.        inA.GetProperty( i, kpidSize, size );
  2293.        inA.GetProperty( i, kpidPackedSize, packedsize );
  2294.        inA.GetProperty( i, kpidAttributes, attr );
  2295.        inA.GetProperty( i, kpidCRC, fcrc );
  2296.        inA.GetProperty( i, kpidMethod, szMethod );
  2297.        inA.GetProperty( i, kpidLastWriteTime, sztime );
  2298.        inA.GetProperty( i, kpidblock, blockpid );
  2299.        try
  2300.        if ( ( ( attr.uiVal and ( 1 shl 4 ) ) <> 0 ) or ( size.uhVal.QuadPart = 0 ) ) then szMethod_WS := 'None'  // is a directory or 0byte file
  2301.         else  //rg 18.04.06
  2302.          szMethod_WS := Widestring( szmethod.bstrVal ); //Check for diectoies or 0 byte files, if not an exception happens
  2303.        //ErikGG Begin 07.11.06
  2304.        //Add all found files and directories to the Files List
  2305.        //Is it a directory then add only paths with the backslash
  2306.        if ( ( attr.uiVal and ( 1 shl 4 ) ) <> 0 ) then
  2307.         ffiles.AddString( Widestring( AppendSlash( path.bstrVal ) ) )
  2308.        else
  2309.         ffiles.AddString( Widestring( path.bstrVal ) );
  2310.        //ErikGG End 07.11.06
  2311.        if assigned( Fonlistfile ) then
  2312.           Fonlistfile( self,
  2313.             Widestring( path.bstrVal ),  //filename 1
  2314.             i,                         //fileindex for extracting
  2315.             size.uhVal.QuadPart,       //Filesizeunp  2
  2316.             packedsize.uhVal.QuadPart, //FilesizeP 3
  2317.             ( attr.uhVal.QuadPart and not ( 1 shl 13 ) ), //attr 4 , removes first set bit
  2318.             fcrc.uhVal.QuadPart,       //CRC 5
  2319.             szMethod_WS,               //method 6
  2320.             FileTimeToDateTime( sztime.filetime,2 )  //filetime 7
  2321.             );
  2322.        except
  2323.        end;
  2324.    end; //for i:= 0
  2325.    Result := FNumberOfFiles;
  2326. finally
  2327.    ina.Close;
  2328.    ResetCancel;
  2329. end;
  2330. end;
  2331. /////// Added MK 30.03.2006
  2332. // ErikGG 07.11.06 Rewrote the add method,
  2333. function TSevenZip.Add: Integer;
  2334. var
  2335.   updateCallback: TMyArchiveUpdateCallback;
  2336.   intf: IArchiveUpdateCallback;
  2337.   outStream: IOutStream;
  2338.   i,a,FileAttr{, FtoAdd, fHnd}: Integer;
  2339.   FMaxProgress:int64;
  2340.   FileDT:TFiletime;
  2341.   FileSize_:int64;
  2342.   setProperties: ISetProperties;
  2343.   SetP: array[ 0..10 ] of PROPVARIANT;
  2344.   SetPNames: array[ 0..2 ] of PWideChar;
  2345.   FilesinBuffer, CurrBuffSize, NumOfProps: Cardinal;
  2346. //Get compression strength for adding
  2347.   function SevenZipCompressionStrengthInt( cs: TCompressStrength ): Cardinal;
  2348.   begin
  2349.     case cs of
  2350.       SAVE: result := 0;
  2351.       FAST: result := 3;
  2352.       NORMAL: result := 5;
  2353.       MAXIMUM: result := 7;
  2354.       ULTRA: result := 9;
  2355.     else
  2356.       result := 5;
  2357.     end;
  2358.   end;
  2359. // Shadow 28.11.2006
  2360. //Get directory content and recursive if wanted
  2361. //------------------------------------------------------------------------------
  2362.   procedure AddFile( _Name: WideString; _Size: Int64; _DateTime: _FILETIME; _Attr: Cardinal );
  2363.   begin
  2364.     if CurrBuffSize <= FilesinBuffer then begin //Increase the Buffers by 100 entries.
  2365.       Inc( CurrBuffSize, 100 );
  2366.       Setlength( updateCallback.Files, CurrBuffSize );
  2367.       Setlength( updateCallback.Files_size, CurrBuffSize );
  2368.       Setlength( updateCallback.Files_Date, CurrBuffSize );
  2369.       Setlength( updateCallback.Files_Attr, CurrBuffSize );
  2370.     end;
  2371.     updateCallback.Files[ FilesinBuffer ] := _Name;
  2372.     updateCallback.Files_size[ FilesinBuffer ] := _Size;
  2373.     updateCallback.Files_Date[ FilesinBuffer ] := _DateTime;
  2374.     updateCallback.Files_Attr[ FilesinBuffer ] := _Attr;
  2375.     FMaxProgress := FMaxProgress + _Size;
  2376.     Inc( FilesinBuffer );
  2377.   end;
  2378.   procedure AddRootDir( const Dir: WideString );
  2379.   var
  2380.     s: WideString;
  2381.     l: Integer;
  2382.   begin
  2383.     s := ClearSlash( Dir );
  2384.     if not DirectoryExistsW( s ) then Exit;
  2385.     GetFileSizeandDateTime_Int64( s, FileSize_, FileDT, FileAttr );
  2386.     l := Length( s );
  2387.     while ( l > 0 ) and ( s[ l ] <> '' ) do Dec( l );
  2388.     s := Copy( s, l + 1, MaxInt );
  2389.     AddFile( s, FileSize_, FileDT, FileAttr );
  2390.   end;
  2391.   procedure GetDirs( Const MainDir, Ext: WideString );
  2392.   var
  2393.     srw: _Win32_Find_Dataw;
  2394.     SearchHandle: Cardinal;
  2395.   begin
  2396.     srw.dwFileAttributes := faAnyFile;
  2397.     SearchHandle := FindFirstFileW( PWideChar( MainDir + '*.*' ), srw );
  2398.     if SearchHandle <> INVALID_HANDLE_VALUE then begin
  2399.       repeat
  2400.         if ( srw.cFileName[ 0 ] = '.' ) then Continue; //Blocks "." and ".." filenames
  2401.         if ( ( srw.dwFileAttributes and faDirectory ) = faDirectory ) then begin//Is a Directory
  2402.           Addfile(
  2403.             MainDir + srw.cFileName,
  2404.             srw.nFileSizeHigh shl 32 + srw.nFileSizeLow,
  2405.             srw.ftLastWriteTime,
  2406.             srw.dwFileAttributes
  2407.           );
  2408.           if ( AddRecurseDirs in FAddoptions ) then GetDirs( AppendSlash( MainDir + srw.cFileName ), Ext );
  2409.         end else begin //Is a file
  2410.           if ( Ext <> '.*' ) and ( ExtractFileExtW( srw.cFileName ) <> Ext ) then Continue;
  2411.           Addfile(
  2412.             MainDir + srw.cFileName,
  2413.             srw.nFileSizeHigh shl 32 + srw.nFileSizeLow,
  2414.             srw.ftLastWriteTime,
  2415.             srw.dwFileAttributes
  2416.           );
  2417.         end;
  2418.       until not FindNextFileW( SearchHandle, srw ) or FMainCancel;
  2419.       Windows.FindClose( SearchHandle );
  2420.     end;
  2421.   end;
  2422. {
  2423.      procedure SetPassword( Password: String );
  2424.      var
  2425.        CryptoSetPassword: ICryptoSetPassword;
  2426.        Buffer: PChar;
  2427.        SizeInBytes: DWORD;
  2428.        i: Integer;
  2429.      begin
  2430.        if not Assigned( SetPwd ) then Exit;
  2431.        if SetPwd.QueryInterface( IID_ICryptoSetPassword, CryptoSetPassword ) = S_OK then begin
  2432.          SizeInBytes := Length( Password ) * 2;
  2433.          GetMem( Buffer, SizeInBytes );
  2434.          try
  2435.            for i := 0 to Length( Password ) - 1 do begin
  2436.              Buffer[ i * 2 ] := Password[ i + 1 ];
  2437.              Buffer[ i * 2 + 1 ] := #0;
  2438.            end;
  2439.            CryptoSetPassword.CryptoSetPassword( Buffer, SizeInBytes );
  2440.           finally
  2441.            FreeMem( Buffer );
  2442.          end;
  2443.         end;
  2444.      end;
  2445. }
  2446. begin //main procedure
  2447.   try
  2448.     updateCallback := TMyArchiveUpdateCallback.Create( self );
  2449. // Set FRootDir to uppercase for comparing
  2450. // Set AddRootdir for relative path or wholepath
  2451. // Set Frootdir to '' to add whole path
  2452.     FRootDir := UppercaseW_( FRootDir );
  2453.     updateCallback.RootDir := AppendSlash( FRootDir );
  2454.     FMaxProgress := 0;
  2455.     FilesinBuffer := 0;
  2456.     CurrBuffSize := 0;
  2457.     for i := 0 to Ffiles.Count- 1 do begin
  2458. //Contains a directory in the sence of C:DIR*.*
  2459.       a := Pos( '*', Ffiles.WStrings[ i ] );
  2460.       if a > 0 then begin
  2461.         AddRootDir( AppendSlash( Copy( Ffiles.WStrings[ i ], 1, a-1 ) ) );
  2462.         GetDirs( AppendSlash( Copy( Ffiles.WStrings[ i ], 1, a-1 ) ), Copy( ffiles.WStrings[ i ], a + 1, 8 ) );
  2463.       end else if FileExists_( Ffiles.WStrings[ i ] ) then begin
  2464.         GetFileSizeandDateTime_Int64( Ffiles.Wstrings[ i ],FileSize_, FileDT, FileAttr );
  2465.         AddFile( Ffiles.Wstrings[ i ], FileSize_, FileDT, FileAttr );
  2466.       end;
  2467.     end;
  2468. //Reset the Buffers back to the size equaling the number of files.
  2469.     SetLength( updateCallback.Files, FilesinBuffer );
  2470.     SetLength( updateCallback.Files_size, FilesinBuffer );
  2471.     SetLength( updateCallback.Files_Date, FilesinBuffer );
  2472.     SetLength( updateCallback.Files_Attr, FilesinBuffer );
  2473. //send MaxProgress to App
  2474.     if Assigned( OnPreProgress ) then OnPreProgress( Self, FMaxProgress );
  2475.   if ( FSFXCreate ) and ( FileExists_( FSFXModule ) ) then begin
  2476.     FSevenZipFileName := ChangeFileExtW( FSevenZipFileName,'.exe' );
  2477.     if CopyFileW( PWidechar( SFXModule ), PWideChar( FSevenZipFileName ), True ) then
  2478. // Shadow 27.11.2006
  2479.      outStream := TMyStreamWriter.Create( FSevenZipFileName, Now, FILE_ATTRIBUTE_ARCHIVE, FVolumeSize, TRUE )
  2480.     else begin
  2481.        if Assigned( onMessage ) then
  2482.         OnMessage( self, 1, 'Could not create SFX', '' );
  2483.      end;
  2484.    end else
  2485.    outStream := TMyStreamWriter.Create( FSevenZipFileName, now, FILE_ATTRIBUTE_ARCHIVE, FVolumeSize, FALSE );
  2486.   //_______________
  2487.   //Setp.vt := VT_EMPTY;
  2488.   //Set archive options
  2489.   if outA.QueryInterface( IID_ISetProperties, setProperties ) = S_OK then begin
  2490.     NumOfProps := 0;
  2491.     //rg 17.04.06
  2492.     case FCompressType of
  2493.      LZMA: begin
  2494.             // 7z Profile
  2495.             Setp[ NumOfProps ].vt := VT_UI4;
  2496.             SetPNames[ NumOfProps ] := StringToOleStr( 'X' );
  2497.             Setp[ NumOfProps ].ulVal := SevenZipCompressionStrengthInt( FCompstrength );
  2498.             inc( NumOfProps );
  2499.             //Solid
  2500.             Setp[ NumOfProps ].vt := VT_BSTR;
  2501.             SetPNames[ NumOfProps ] := StringToOleStr( 's' );
  2502.             if ( AddSolid in FAddoptions ) then
  2503.              Setp[ NumOfProps ].bstrVal := SysAllocString( 'on' )
  2504.             else
  2505.              Setp[ NumOfProps ].bstrVal := SysAllocString( 'off' );
  2506.             inc( NumOfProps );
  2507.             {
  2508.             directorysize 0..27
  2509.             No need to set if you use CompressionStrength Profiles
  2510.             ( Save...Ultra )
  2511.             }
  2512.             if FLZMAStrength > 0 then
  2513.              begin
  2514.               Setp[ NumOfProps ].vt := VT_UI4;
  2515.               SetPNames[ NumOfProps ] := StringToOleStr( 'd' );
  2516.               Setp[ NumOfProps ].ulVal := FLZMAStrength;
  2517.               inc( NumOfProps )
  2518.              end;
  2519.           end;
  2520.      PPMD: begin
  2521.             // PPMD compression
  2522.             Setp[ NumOfProps ].vt := VT_BSTR;
  2523.             SetPNames[ NumOfProps ] := StringToOleStr( '0' );
  2524.             Setp[ NumOfProps ].bstrVal := SysAllocString( 'PPMd' );
  2525.             inc( NumOfProps );
  2526.             //PPMD Size
  2527.             //No need to set if you use defaults
  2528.             if FPPMDsize > 0 then
  2529.              begin
  2530.               Setp[ NumOfProps ].vt := VT_UI4;
  2531.               SetPNames[ NumOfProps ] := StringToOleStr( 'o' );
  2532.               Setp[ NumOfProps ].ulVal := 10;
  2533.               inc( NumOfProps );
  2534.              end;
  2535.             //PPMD Mem
  2536.             //No need to set if you use defaults
  2537.             if FPPMDmem > 0 then
  2538.              begin
  2539.               Setp[ NumOfProps ].vt := VT_UI4;
  2540.               SetPNames[ NumOfProps ] := StringToOleStr( 'mem' );
  2541.               Setp[ NumOfProps ].ulVal := 30;
  2542.               inc( NumOfProps );
  2543.              end;
  2544.            end;
  2545.     end; //end case
  2546.     if (FPassword <> '') and ( AddEnCryptFilename in FAddoptions ) then
  2547.       begin  
  2548.         Setp[ NumOfProps ].vt := VT_BSTR;
  2549.         SetPNames[ NumOfProps ] := StringToOleStr( 'he' );
  2550.         Setp[ NumOfProps ].bstrVal := SysAllocString( 'on' );
  2551.         inc( NumOfProps );
  2552.       end;
  2553.     // set options
  2554.     result := setProperties.SetProperties( @SetPNames, @Setp, NumOfProps );
  2555.    end; //if QuerryInterface
  2556.   //____________________
  2557.   if FilesinBuffer > 0 then Begin
  2558.     intf := updateCallback;
  2559.     Result := outA.UpdateItems( outStream, FilesinBuffer, updateCallback );
  2560.   end else begin
  2561.     if Assigned( OnMessage ) then OnMessage( Self, 1, 'No files to add.', '' );
  2562.     Result := -1;
  2563.   end;
  2564.  finally
  2565.   ResetCancel;
  2566.  end;
  2567. end;
  2568. function TSevenZip.Extract( TestArchive:Boolean=False ): Integer;
  2569. var
  2570.   updateCallback: TMyArchiveExtractCallback;
  2571.   updateOpenCallback: TmyArchiveOpenCallback;
  2572.   ms: TMyStreamReader;
  2573.   filesDW: array of DWORD;
  2574.   Filestoex,w: DWORD;
  2575.   i,j,n: Integer;
  2576.   FMaxProgress:int64;
  2577.   size: PROPVARIANT;
  2578. // Lifepower (07-Jan-2007):
  2579. //  Commented unused variables
  2580. //  fnameprop: PROPVARIANT;
  2581. //  fileInArchive, fileToExtract: WideString;
  2582. begin
  2583. try
  2584. // 24.08.06 - Matteo Riso - Status: experimental
  2585. // 25.08.06 Modified by rg
  2586. //
  2587. // If we loaded an .EXE file, we could start reading from offset 132096.
  2588. // Also supported by newerdll
  2589. //  if FIsSFX then ms.Seek( FSFXOffset,0,@FSFXOffset );
  2590. // End - MR modification
  2591. // Shadow 28.11.2006
  2592.     if UppercaseW_( ExtractFileExtW( FSevenZipFileName ) ) = '.EXE' then begin
  2593.       if not SFXCheck( FSevenZipFileName ) then begin
  2594.         Result := -1;
  2595.         if assigned( onMessage ) then onMessage( self, 7, 'File is not an 7z SFX archive', Fsevenzipfilename );
  2596.         Exit;
  2597.       end;
  2598.     end;
  2599.     ms := TMyStreamReader.Create( Self, FSevenZipFileName, TRUE );
  2600.     inA.Close;
  2601.     updateOpenCallback := TMyArchiveOpenCallback.Create( self );
  2602.     i := inA.Open( ms, nil, updateOpenCallback );
  2603.     if i <> 0 then begin
  2604.       Result := -1;
  2605.       if assigned( onMessage ) then onMessage( self,1,'File not found',FSevenZipFileName );
  2606.       ms.Free;
  2607.       Exit;
  2608.     end;
  2609.     FMaxProgress := 0;
  2610.     inA.GetNumberOfItems( w ); //1..end
  2611.     dec( w ); //Starting with 0..end-1
  2612.     n := 0;
  2613.     if FFiles.Count > 0 then begin
  2614.       SetLength( filesDW, ffiles.Count );
  2615.       for i := 0 to FFiles.count - 1 do begin
  2616.         if not TryStrToInt_( Ffiles.WStrings[ i ], j ) then
  2617.           j := GetINdexbyFilename( Ffiles.WStrings[ i ] );
  2618.           // Lifepower (07-Jan-2007):
  2619.           //  Added typecast to prevent warning.
  2620.           if (j < 0) or (Int64(j) > w) then begin
  2621.             if Assigned( onMessage ) then onMessage( Self, 5, 'Index out of Range', '' );
  2622.             Result := -1;
  2623.             Exit;
  2624.           end;
  2625.           size.vt := VT_EMPTY;
  2626.           inA.GetProperty( j, kpidSize, size );
  2627.           FMaxProgress := FMaxprogress + size.uhVal.QuadPart;
  2628.           filesDW[ n ] := j;
  2629.           Inc( n );
  2630.         end; // For i := 0
  2631.       Filestoex := n;
  2632.     end else begin
  2633. //   extract all files, FFiles.Count must be 0
  2634.      FilestoEx := $FFFFFFFF;
  2635.     end;
  2636.     SetLength( filesDW, n );
  2637. //set FMaxProgress for selected files
  2638.   if FMaxProgress > 0 then if assigned( OnPreProgress ) then OnPreProgress( self,FMaxProgress );
  2639. // filesdw must be sorted asc
  2640.   if length( filesdw ) > 1 then SortDWord( filesDW,low( filesdw ),High( filesdw ) );
  2641.   updatecallback := TMyArchiveExtractCallback.Create( self );
  2642.   updatecallback.FExtractDirectory := appendslash( Fextrbasedir );
  2643.   updatecallback.FFilestoextract   := ffiles.Count; //with all files ffiles.count = 0, thats ok
  2644.   updatecallback.FAllFilesExt      := false;        //Stop extracting if no more files to extract
  2645.   updatecallback.FLastFileToExt    := false;        //only 1 more to extact
  2646.   result := inA.Extract( @filesDW[ 0 ], Filestoex, Integer( TestArchive ), updatecallback )
  2647. //  mmoLog.Lines.Add( Format( 'IInArchive.Extract: %d', [ result ] ) );
  2648. finally
  2649.   ina.close;
  2650.   ResetCancel;
  2651. end;
  2652. end;
  2653. (*
  2654. function TSevenZip.Delete: Integer;
  2655. begin
  2656. //
  2657. end;
  2658. *)
  2659. //------------------------------------------------------------------------------------------------
  2660. //------------------------------------------------------------------------------------------------
  2661. //-----------------End SevenZip VCL---------------------------------------------------------
  2662. //------------------------------------------------------------------------------------------------
  2663. //------------------------------------------------------------------------------------------------
  2664. procedure Register;
  2665. begin
  2666.   RegisterComponents( 'Seven Zip', [ TSevenZip ] );
  2667. end;
  2668. end.