主页 > 编程资料 > Delphi >
发布时间:2015-09-22 作者:网络 阅读:178次

delphi的示例程序从这里下载:http://www.progdigy.com/files/sevenzip.zip

This API use the 7-zip dll (7z.dll) to read and write all 7-zip supported archive formats.

- Autor: Henri Gourvest
- Licence: MPL1.1
- Date: 15/04/2009
- Version: 1.1

Reading archive:

Extract to path:

 with CreateInArchive(CLSID_CFormatZip) do
begin
OpenFile('c:\test.zip',',',');
ExtractTo(
'c:\test',',',');
end;

Get file list:

 with CreateInArchive(CLSID_CFormat7z) do
begin
OpenFile('c:\test.7z',',',');
for i := 0 to NumberOfItems - 1 do
if not ItemIsFolder[i] then
Writeln(ItemPath[i],',',');
end;

Extract to stream

 with CreateInArchive(CLSID_CFormat7z) do
begin
OpenFile('c:\test.7z',',',');
for i := 0 to NumberOfItems - 1 do
if not ItemIsFolder[i] then
ExtractItem(i, stream, false,',',');
end;

Extract "n" Items

function GetStreamCallBack(sender: Pointer; index: Cardinal;
var outStream: ISequentialOutStream): HRESULT; stdcall;
begin
case index of ...
outStream := T7zStream.Create(aStream, soReference,',',');
Result := S_OK;
end;

procedure TMainForm.ExtractClick(Sender: TObject,',',');
var
i: integer;
items:
array[0..2] of Cardinal;
begin
with CreateInArchive(CLSID_CFormat7z) do
begin
OpenFile('c:\test.7z',',',');
// items must be sorted by index!
items[0] := 0;
items[
1] := 1;
items[
2] := 2;
ExtractItems(@items, Length(items), false,
nil, GetStreamCallBack,',',');
end;
end;

Open stream

 with CreateInArchive(CLSID_CFormatZip) do
begin
OpenStream(T7zStream.Create(TFileStream.Create('c:\test.zip', fmOpenRead), soOwned),',',');
OpenStream(aStream, soReference,',',');
...
end;

Progress bar

 function ProgressCallback(sender: Pointer; total: boolean; value: int64): HRESULT; stdcall;
begin
if total then
Mainform.ProgressBar.Max := value else
Mainform.ProgressBar.Position := value;
Result := S_OK;
end;

procedure TMainForm.ExtractClick(Sender: TObject,',',');
begin
with CreateInArchive(CLSID_CFormatZip) do
begin
OpenFile('c:\test.zip',',',');
SetProgressCallback(
nil, ProgressCallback,',',');
...
end;
end;

Password

 function PasswordCallback(sender: Pointer; var password: WideString): HRESULT; stdcall;
begin
// call a dialog box ...
password := 'password';
Result := S_OK;
end;

procedure TMainForm.ExtractClick(Sender: TObject,',',');
begin
with CreateInArchive(CLSID_CFormatZip) do
begin
// using callback
SetPasswordCallback(nil, PasswordCallback,',',');
// or setting password directly
SetPassword('password',',',');
OpenFile(
'c:\test.zip',',',');
...
end;
end;

Writing archive

 procedure TMainForm.ExtractAllClick(Sender: TObject,',',');
var
Arch: I7zOutArchive;
begin
Arch := CreateOutArchive(CLSID_CFormat7z,',',');
// add a file
Arch.AddFile('c:\test.bin', 'folder\test.bin',',',');
// add files using willcards and recursive search
Arch.AddFiles('c:\test', 'folder', '*.pas;*.dfm', true,',',');
// add a stream
Arch.AddStream(aStream, soReference, faArchive, CurrentFileTime, CurrentFileTime, 'folder\test.bin', false, false,',',');
// compression level
SetCompressionLevel(Arch, 5,',',');
// compression method if <> LZMA
SevenZipSetCompressionMethod(Arch, m7BZip2,',',');
// add a progress bar ...
Arch.SetProgressCallback(...,',',');
// set a password if necessary
Arch.SetPassword('password',',',');
// Save to file
Arch.SaveToFile('c:\test.zip',',',');
// or a stream
Arch.SaveToStream(aStream,',',');
end;

 

sevenzip.pas

(********************************************************************************)(* 7-ZIP DELPHI API *)(* *)(* The contents of this file are subject to the Mozilla Public License Version *)(* 1.1 (the "License",',','); you may not use this file except in compliance with the *)(* License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ *)(* *)(* Software distributed under the License is distributed on an "AS IS" basis, *)(* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for *)(* the specific language governing rights and limitations under the License. *)(* *)(* Unit owner : Henri Gourvest <hgourvest@gmail.com> *)(* V1.2 *)(********************************************************************************) unit sevenzip;{$ALIGN ON}{$MINENUMSIZE 4}{$WARN SYMBOL_PLATFORM OFF} interfaceuses SysUtils, Windows, ActiveX, Classes, Contnrs; type PVarType = ^TVarType; PCardArray = ^TCardArray; TCardArray = array[0..MaxInt div SizeOf(Cardinal) - 1] of Cardinal; {$IFNDEF UNICODE} UnicodeString = WideString;{$ENDIF} //******************************************************************************// PropID.h//****************************************************************************** const kpidNoProperty = 0; kpidHandlerItemIndex = 2; kpidPath = 3; // VT_BSTR kpidName = 4; // VT_BSTR kpidExtension = 5; // VT_BSTR kpidIsFolder = 6; // VT_BOOL kpidSize = 7; // VT_UI8 kpidPackedSize = 8; // VT_UI8 kpidAttributes = 9; // VT_UI4 kpidCreationTime = 10; // VT_FILETIME kpidLastAccessTime = 11; // VT_FILETIME kpidLastWriteTime = 12; // VT_FILETIME kpidSolid = 13; // VT_BOOL kpidCommented = 14; // VT_BOOL kpidEncrypted = 15; // VT_BOOL kpidSplitBefore = 16; // VT_BOOL kpidSplitAfter = 17; // VT_BOOL kpidDictionarySize = 18; // VT_UI4 kpidCRC = 19; // VT_UI4 kpidType = 20; // VT_BSTR kpidIsAnti = 21; // VT_BOOL kpidMethod = 22; // VT_BSTR kpidHostOS = 23; // VT_BSTR kpidFileSystem = 24; // VT_BSTR kpidUser = 25; // VT_BSTR kpidGroup = 26; // VT_BSTR kpidBlock = 27; // VT_UI4 kpidComment = 28; // VT_BSTR kpidPosition = 29; // VT_UI4 kpidPrefix = 30; // VT_BSTR kpidNumSubDirs = 31; // VT_UI4 kpidNumSubFiles = 32; // VT_UI4 kpidUnpackVer = 33; // VT_UI1 kpidVolume = 34; // VT_UI4 kpidIsVolume = 35; // VT_BOOL kpidOffset = 36; // VT_UI8 kpidLinks = 37; // VT_UI4 kpidNumBlocks = 38; // VT_UI4 kpidNumVolumes = 39; // VT_UI4 kpidTimeType = 40; // VT_UI4 kpidBit64 = 41; // VT_BOOL kpidBigEndian = 42; // VT_BOOL kpidCpu = 43; // VT_BSTR kpidPhySize = 44; // VT_UI8 kpidHeadersSize = 45; // VT_UI8 kpidChecksum = 46; // VT_UI4 kpidCharacts = 47; // VT_BSTR kpidVa = 48; // VT_UI8 kpidTotalSize = $1100; // VT_UI8 kpidFreeSpace = kpidTotalSize + 1; // VT_UI8 kpidClusterSize = kpidFreeSpace + 1; // VT_UI8 kpidVolumeName = kpidClusterSize + 1; // VT_BSTR kpidLocalName = $1200; // VT_BSTR kpidProvider = kpidLocalName + 1; // VT_BSTR kpidUserDefined = $10000; //******************************************************************************// IProgress.h//******************************************************************************type IProgress = interface(IUnknown) ['{23170F69-40C1-278A-0000-000000050000}'] function SetTotal(total: Int64): HRESULT; stdcall; function SetCompleted(completeValue: PInt64): HRESULT; stdcall; end; //******************************************************************************// IPassword.h//****************************************************************************** ICryptoGetTextPassword = interface(IUnknown) ['{23170F69-40C1-278A-0000-000500100000}'] function CryptoGetTextPassword(var password: TBStr): HRESULT; stdcall; end; ICryptoGetTextPassword2 = interface(IUnknown) ['{23170F69-40C1-278A-0000-000500110000}'] function CryptoGetTextPassword2(passwordIsDefined: PInteger; var password: TBStr): HRESULT; stdcall; end; //******************************************************************************// IStream.h// "23170F69-40C1-278A-0000-000300xx0000"//****************************************************************************** ISequentialInStream = interface(IUnknown) ['{23170F69-40C1-278A-0000-000300010000}'] function Read(data: Pointer; size: Cardinal; processedSize: PCardinal): HRESULT; stdcall; (* Out: if size != 0, return_value = S_OK and (*processedSize == 0), then there are no more bytes in stream. if (size > 0) && there are bytes in stream, this function must read at least 1 byte. This function is allowed to read less than number of remaining bytes in stream. You must call Read function in loop, if you need exact amount of data *) end; ISequentialOutStream = interface(IUnknown) ['{23170F69-40C1-278A-0000-000300020000}'] function Write(data: Pointer; size: Cardinal; processedSize: PCardinal): HRESULT; stdcall; (* if (size > 0) this function must write at least 1 byte. This function is allowed to write less than "size". You must call Write function in loop, if you need to write exact amount of data *) end; IInStream = interface(ISequentialInStream) ['{23170F69-40C1-278A-0000-000300030000}'] function Seek(offset: Int64; seekOrigin: Cardinal; newPosition: PInt64): HRESULT; stdcall; end; IOutStream = interface(ISequentialOutStream) ['{23170F69-40C1-278A-0000-000300040000}'] function Seek(offset: Int64; seekOrigin: Cardinal; newPosition: PInt64): HRESULT; stdcall; function SetSize(newSize: Int64): HRESULT; stdcall; end; IStreamGetSize = interface(IUnknown) ['{23170F69-40C1-278A-0000-000300060000}'] function GetSize(size: PInt64): HRESULT; stdcall; end; IOutStreamFlush = interface(IUnknown) ['{23170F69-40C1-278A-0000-000300070000}'] function Flush: HRESULT; stdcall; end; //******************************************************************************// IArchive.h//****************************************************************************** // MIDL_INTERFACE("23170F69-40C1-278A-0000-000600xx0000")//#define ARCHIVE_INTERFACE_SUB(i, base, x) \//DEFINE_GUID(IID_ ## i, \//0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x06, 0x00, x, 0x00, 0x00,',','); \//struct i: public base //#define ARCHIVE_INTERFACE(i, x) ARCHIVE_INTERFACE_SUB(i, IUnknown, x) type// NFileTimeType NFileTimeType = ( kWindows = 0, kUnix, kDOS ,',','); // NArchive:: NArchive = ( kName = 0, // string kClassID, // GUID kExtension, // string zip rar gz kAddExtension, // sub archive: tar kUpdate, // bool kKeepName, // bool kStartSignature, // string[4] ex: PK.. 7z.. Rar! kFinishSignature, kAssociate ,',','); // NArchive::NExtract::NAskMode NAskMode = ( kExtract = 0, kTest, kSkip ,',','); // NArchive::NExtract::NOperationResult NExtOperationResult = ( kOK = 0, kUnSupportedMethod, kDataError, kCRCError ,',','); // NArchive::NUpdate::NOperationResult NUpdOperationResult = ( kOK_ = 0, kError ,',','); IArchiveOpenCallback = interface ['{23170F69-40C1-278A-0000-000600100000}'] function SetTotal(files, bytes: PInt64): HRESULT; stdcall; function SetCompleted(files, bytes: PInt64): HRESULT; stdcall; end; IArchiveExtractCallback = interface(IProgress) ['{23170F69-40C1-278A-0000-000600200000}'] function GetStream(index: Cardinal; var outStream: ISequentialOutStream; askExtractMode: NAskMode): HRESULT; stdcall; // GetStream OUT: S_OK - OK, S_FALSE - skeep this file function PrepareOperation(askExtractMode: NAskMode): HRESULT; stdcall; function SetOperationResult(resultEOperationResult: NExtOperationResult): HRESULT; stdcall; end; IArchiveOpenVolumeCallback = interface ['{23170F69-40C1-278A-0000-000600300000}'] function GetProperty(propID: PROPID; var value: OleVariant): HRESULT; stdcall; function GetStream(const name: PWideChar; var inStream: IInStream): HRESULT; stdcall; end; IInArchiveGetStream = interface ['{23170F69-40C1-278A-0000-000600400000}'] function GetStream(index: Cardinal; var stream: ISequentialInStream ): HRESULT; stdcall; end; IArchiveOpenSetSubArchiveName = interface ['{23170F69-40C1-278A-0000-000600500000}'] function SetSubArchiveName(name: PWideChar): HRESULT; stdcall; end; IInArchive = interface ['{23170F69-40C1-278A-0000-000600600000}'] function Open(stream: IInStream; const maxCheckStartPosition: PInt64; openArchiveCallback: IArchiveOpenCallback): HRESULT; stdcall; function Close: HRESULT; stdcall; function GetNumberOfItems(var numItems: CArdinal): HRESULT; stdcall; function GetProperty(index: Cardinal; propID: PROPID; var value: OleVariant): HRESULT; stdcall; function Extract(indices: PCardArray; numItems: Cardinal; testMode: Integer; extractCallback: IArchiveExtractCallback): HRESULT; stdcall; // indices must be sorted // numItems = 0xFFFFFFFF means all files // testMode != 0 means "test files operation" function GetArchiveProperty(propID: PROPID; var value: OleVariant): HRESULT; stdcall; function GetNumberOfProperties(numProperties: PCardinal): HRESULT; stdcall; function GetPropertyInfo(index: Cardinal; name: PBSTR; propID: PPropID; varType: PVarType): HRESULT; stdcall; function GetNumberOfArchiveProperties(var numProperties: Cardinal): HRESULT; stdcall; function GetArchivePropertyInfo(index: Cardinal; name: PBSTR; propID: PPropID; varType: PVARTYPE): HRESULT; stdcall; end; IArchiveUpdateCallback = interface(IProgress) ['{23170F69-40C1-278A-0000-000600800000}'] function GetUpdateItemInfo(index: Cardinal; newData: PInteger; // 1 - new data, 0 - old data newProperties: PInteger; // 1 - new properties, 0 - old properties indexInArchive: PCardinal // -1 if there is no in archive, or if doesn't matter ): HRESULT; stdcall; function GetProperty(index: Cardinal; propID: PROPID; var value: OleVariant): HRESULT; stdcall; function GetStream(index: Cardinal; var inStream: ISequentialInStream): HRESULT; stdcall; function SetOperationResult(operationResult: Integer): HRESULT; stdcall; end; IArchiveUpdateCallback2 = interface(IArchiveUpdateCallback) ['{23170F69-40C1-278A-0000-000600820000}'] function GetVolumeSize(index: Cardinal; size: PInt64): HRESULT; stdcall; function GetVolumeStream(index: Cardinal; var volumeStream: ISequentialOutStream): HRESULT; stdcall; end; IOutArchive = interface ['{23170F69-40C1-278A-0000-000600A00000}'] function UpdateItems(outStream: ISequentialOutStream; numItems: Cardinal; updateCallback: IArchiveUpdateCallback): HRESULT; stdcall; function GetFileTimeType(type_: PCardinal): HRESULT; stdcall; end; ISetProperties = interface ['{23170F69-40C1-278A-0000-000600030000}'] function SetProperties(names: PPWideChar; values: PPROPVARIANT; numProperties: Integer): HRESULT; stdcall; end; //******************************************************************************// ICoder.h// "23170F69-40C1-278A-0000-000400xx0000"//****************************************************************************** ICompressProgressInfo = interface ['{23170F69-40C1-278A-0000-000400040000}'] function SetRatioInfo(inSize, outSize: PInt64): HRESULT; stdcall; end; ICompressCoder = interface ['{23170F69-40C1-278A-0000-000400050000}'] function Code(inStream, outStream: ISequentialInStream; inSize, outSize: PInt64; progress: ICompressProgressInfo): HRESULT; stdcall; end; ICompressCoder2 = interface ['{23170F69-40C1-278A-0000-000400180000}'] function Code(var inStreams: ISequentialInStream; var inSizes: PInt64; numInStreams: Cardinal; var outStreams: ISequentialOutStream; var outSizes: PInt64; numOutStreams: Cardinal; progress: ICompressProgressInfo): HRESULT; stdcall; end; const//NCoderPropID:: kDictionarySize = $400; kUsedMemorySize = kDictionarySize + 1; kOrder = kUsedMemorySize + 1; kPosStateBits = $440; kLitContextBits = kPosStateBits + 1; kLitPosBits = kLitContextBits + 1; kNumFastBytes = $450; kMatchFinder = kNumFastBytes + 1; kMatchFinderCycles = kMatchFinder + 1; kNumPasses = $460; kAlgorithm = $470; kMultiThread = $480; kNumThreads = kMultiThread + 1; kEndMarker = $490; type ICompressSetCoderProperties = interface ['{23170F69-40C1-278A-0000-000400200000}'] function SetCoderProperties(propIDs: PPropID; properties: PROPVARIANT; numProperties: Cardinal): HRESULT; stdcall; end; (*CODER_INTERFACE(ICompressSetCoderProperties, 0x21){ STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream) PURE;};*) ICompressSetDecoderProperties2 = interface ['{23170F69-40C1-278A-0000-000400220000}'] function SetDecoderProperties2(data: PByte; size: Cardinal): HRESULT; stdcall; end; ICompressWriteCoderProperties = interface ['{23170F69-40C1-278A-0000-000400230000}'] function WriteCoderProperties(outStreams: ISequentialOutStream): HRESULT; stdcall; end; ICompressGetInStreamProcessedSize = interface ['{23170F69-40C1-278A-0000-000400240000}'] function GetInStreamProcessedSize(value: PInt64): HRESULT; stdcall; end; ICompressSetCoderMt = interface ['{23170F69-40C1-278A-0000-000400250000}'] function SetNumberOfThreads(numThreads: Cardinal): HRESULT; stdcall; end; ICompressGetSubStreamSize = interface ['{23170F69-40C1-278A-0000-000400300000}'] function GetSubStreamSize(subStream: Int64; value: PInt64): HRESULT; stdcall; end; ICompressSetInStream = interface ['{23170F69-40C1-278A-0000-000400310000}'] function SetInStream(inStream: ISequentialInStream): HRESULT; stdcall; function ReleaseInStream: HRESULT; stdcall; end; ICompressSetOutStream = interface ['{23170F69-40C1-278A-0000-000400320000}'] function SetOutStream(outStream: ISequentialOutStream): HRESULT; stdcall; function ReleaseOutStream: HRESULT; stdcall; end; ICompressSetInStreamSize = interface ['{23170F69-40C1-278A-0000-000400330000}'] function SetInStreamSize(inSize: PInt64): HRESULT; stdcall; end; ICompressSetOutStreamSize = interface ['{23170F69-40C1-278A-0000-000400340000}'] function SetOutStreamSize(outSize: PInt64): HRESULT; stdcall; end; ICompressFilter = interface ['{23170F69-40C1-278A-0000-000400400000}'] function Init: HRESULT; stdcall; function Filter(data: PByte; size: Cardinal): Cardinal; stdcall; // Filter return outSize (Cardinal) // if (outSize <= size): Filter have converted outSize bytes // if (outSize > size): Filter have not converted anything. // and it needs at least outSize bytes to convert one block // (it's for crypto block algorithms). end; ICryptoProperties = interface ['{23170F69-40C1-278A-0000-000400800000}'] function SetKey(Data: PByte; size: Cardinal): HRESULT; stdcall; function SetInitVector(data: PByte; size: Cardinal): HRESULT; stdcall; end; ICryptoSetPassword = interface ['{23170F69-40C1-278A-0000-000400900000}'] function CryptoSetPassword(data: PByte; size: Cardinal): HRESULT; stdcall; end; ICryptoSetCRC = interface ['{23170F69-40C1-278A-0000-000400A00000}'] function CryptoSetCRC(crc: Cardinal): HRESULT; stdcall; end; //////////////////////// It's for DLL file//NMethodPropID:: NMethodPropID = ( kID = 0, kName_, kDecoder, kEncoder, kInStreams, kOutStreams, kDescription, kDecoderIsAssigned, kEncoderIsAssigned ,',','); //******************************************************************************// CLASSES//****************************************************************************** T7zPasswordCallback = function(sender: Pointer; var password: UnicodeString): HRESULT; stdcall; T7zGetStreamCallBack = function(sender: Pointer; index: Cardinal; var outStream: ISequentialOutStream): HRESULT; stdcall; T7zProgressCallback = function(sender: Pointer; total: boolean; value: int64): HRESULT; stdcall; I7zInArchive = interface ['{022CF785-3ECE-46EF-9755-291FA84CC6C9}'] procedure OpenFile(const filename: string,',','); stdcall; procedure OpenStream(stream: IInStream,',','); stdcall; procedure Close; stdcall; function GetNumberOfItems: Cardinal; stdcall; function GetItemPath(const index: integer): UnicodeString; stdcall; function GetItemName(const index: integer): UnicodeString; stdcall; function GetItemSize(const index: integer): Cardinal; stdcall; function GetItemIsFolder(const index: integer): boolean; stdcall; function GetInArchive: IInArchive; procedure ExtractItem(const item: Cardinal; Stream: TStream; test: longbool,',','); stdcall; procedure ExtractItems(items: PCardArray; count: cardinal; test: longbool; sender: pointer; callback: T7zGetStreamCallBack,',','); stdcall; procedure ExtractAll(test: longbool; sender: pointer; callback: T7zGetStreamCallBack,',','); stdcall; procedure ExtractTo(const path: string,',','); stdcall; procedure SetPasswordCallback(sender: Pointer; callback: T7zPasswordCallback,',','); stdcall; procedure SetPassword(const password: UnicodeString,',','); stdcall; procedure SetProgressCallback(sender: Pointer; callback: T7zProgressCallback,',','); stdcall; procedure SetClassId(const classid: TGUID,',','); function GetClassId: TGUID; property ClassId: TGUID read GetClassId write SetClassId; property NumberOfItems: Cardinal read GetNumberOfItems; property ItemPath[const index: integer]: UnicodeString read GetItemPath; property ItemName[const index: integer]: UnicodeString read GetItemName; property ItemSize[const index: integer]: Cardinal read GetItemSize; property ItemIsFolder[const index: integer]: boolean read GetItemIsFolder; property InArchive: IInArchive read GetInArchive; end; I7zOutArchive = interface ['{BAA9D5DC-9FF4-4382-9BFD-EC9065BD0125}'] procedure AddStream(Stream: TStream; Ownership: TStreamOwnership; Attributes: Cardinal; CreationTime, LastWriteTime: TFileTime; const Path: UnicodeString; IsFolder, IsAnti: boolean,',','); stdcall; procedure AddFile(const Filename: TFileName; const Path: UnicodeString,',','); stdcall; procedure AddFiles(const Dir, Path, Willcards: string; recurse: boolean,',','); stdcall; procedure SaveToFile(const FileName: TFileName,',','); stdcall; procedure SaveToStream(stream: TStream,',','); stdcall; procedure SetProgressCallback(sender: Pointer; callback: T7zProgressCallback,',','); stdcall; procedure CrearBatch; stdcall; procedure SetPassword(const password: UnicodeString,',','); stdcall; procedure SetPropertie(name: UnicodeString; value: OleVariant,',','); stdcall; procedure SetClassId(const classid: TGUID,',','); function GetClassId: TGUID; property ClassId: TGUID read GetClassId write SetClassId; end; I7zCodec = interface ['{AB48F772-F6B1-411E-907F-1567DB0E93B3}'] end; T7zStream = class(TInterfacedObject, IInStream, IStreamGetSize, ISequentialOutStream, ISequentialInStream, IOutStream, IOutStreamFlush) private FStream: TStream; FOwnership: TStreamOwnership; protected function Read(data: Pointer; size: Cardinal; processedSize: PCardinal): HRESULT; stdcall; function Seek(offset: Int64; seekOrigin: Cardinal; newPosition: Pint64): HRESULT; stdcall; function GetSize(size: PInt64): HRESULT; stdcall; function SetSize(newSize: Int64): HRESULT; stdcall; function Write(data: Pointer; size: Cardinal; processedSize: PCardinal): HRESULT; stdcall; function Flush: HRESULT; stdcall; public constructor Create(Stream: TStream; Ownership: TStreamOwnership = soReference,',','); destructor Destroy; override; end; // I7zOutArchive property setterstype TZipCompressionMethod = (mzCopy, mzDeflate, mzDeflate64, mzBZip2,',','); T7zCompressionMethod = (m7Copy, m7LZMA, m7BZip2, m7PPMd, m7Deflate, m7Deflate64,',','); // ZIP 7z GZIP BZ2 procedure SetCompressionLevel(Arch: I7zOutArchive; level: Cardinal,',','); // X X X X procedure SetMultiThreading(Arch: I7zOutArchive; ThreadCount: Cardinal,',','); // X X X procedure SetCompressionMethod(Arch: I7zOutArchive; method: TZipCompressionMethod,',','); // X procedure SetDictionnarySize(Arch: I7zOutArchive; size: Cardinal,',','); // < 32 // X X procedure SetDeflateNumPasses(Arch: I7zOutArchive; pass: Cardinal,',','); // X X X procedure SetNumFastBytes(Arch: I7zOutArchive; fb: Cardinal,',','); // X X procedure SetNumMatchFinderCycles(Arch: I7zOutArchive; mc: Cardinal,',','); // X X procedure SevenZipSetCompressionMethod(Arch: I7zOutArchive; method: T7zCompressionMethod,',','); // X procedure SevenZipSetBindInfo(Arch: I7zOutArchive; const bind: UnicodeString,',','); // X procedure SevenZipSetSolidSettings(Arch: I7zOutArchive; solid: boolean,',','); // X procedure SevenZipRemoveSfxBlock(Arch: I7zOutArchive; remove: boolean,',','); // X procedure SevenZipAutoFilter(Arch: I7zOutArchive; auto: boolean,',','); // X procedure SevenZipCompressHeaders(Arch: I7zOutArchive; compress: boolean,',','); // X procedure SevenZipCompressHeadersFull(Arch: I7zOutArchive; compress: boolean,',','); // X procedure SevenZipEncryptHeaders(Arch: I7zOutArchive; Encrypt: boolean,',','); // X procedure SevenZipVolumeMode(Arch: I7zOutArchive; Mode: boolean,',','); // X // filetime util functions function DateTimeToFileTime(dt: TDateTime): TFileTime; function FileTimeToDateTime(ft: TFileTime): TDateTime; function CurrentFileTime: TFileTime; // constructors function CreateInArchive(const classid: TGUID): I7zInArchive; function CreateOutArchive(const classid: TGUID): I7zOutArchive; const CLSID_CFormatZip : TGUID = '{23170F69-40C1-278A-1000-000110010000}'; // zip jar xpi CLSID_CFormatBZ2 : TGUID = '{23170F69-40C1-278A-1000-000110020000}'; // bz2 bzip2 tbz2 tbz CLSID_CFormatRar : TGUID = '{23170F69-40C1-278A-1000-000110030000}'; // rar r00 CLSID_CFormatArj : TGUID = '{23170F69-40C1-278A-1000-000110040000}'; // arj CLSID_CFormatZ : TGUID = '{23170F69-40C1-278A-1000-000110050000}'; // z taz CLSID_CFormatLzh : TGUID = '{23170F69-40C1-278A-1000-000110060000}'; // lzh lha CLSID_CFormat7z : TGUID = '{23170F69-40C1-278A-1000-000110070000}'; // 7z CLSID_CFormatCab : TGUID = '{23170F69-40C1-278A-1000-000110080000}'; // cab CLSID_CFormatNsis : TGUID = '{23170F69-40C1-278A-1000-000110090000}'; CLSID_CFormatLzma : TGUID = '{23170F69-40C1-278A-1000-0001100A0000}'; // lzma lzma86 CLSID_CFormatPe : TGUID = '{23170F69-40C1-278A-1000-000110DD0000}'; CLSID_CFormatElf : TGUID = '{23170F69-40C1-278A-1000-000110DE0000}'; CLSID_CFormatMacho : TGUID = '{23170F69-40C1-278A-1000-000110DF0000}'; CLSID_CFormatUdf : TGUID = '{23170F69-40C1-278A-1000-000110E00000}'; // iso CLSID_CFormatXar : TGUID = '{23170F69-40C1-278A-1000-000110E10000}'; // xar CLSID_CFormatMub : TGUID = '{23170F69-40C1-278A-1000-000110E20000}'; CLSID_CFormatHfs : TGUID = '{23170F69-40C1-278A-1000-000110E30000}'; CLSID_CFormatDmg : TGUID = '{23170F69-40C1-278A-1000-000110E40000}'; // dmg CLSID_CFormatCompound : TGUID = '{23170F69-40C1-278A-1000-000110E50000}'; // msi doc xls ppt CLSID_CFormatWim : TGUID = '{23170F69-40C1-278A-1000-000110E60000}'; // wim swm CLSID_CFormatIso : TGUID = '{23170F69-40C1-278A-1000-000110E70000}'; // iso CLSID_CFormatBkf : TGUID = '{23170F69-40C1-278A-1000-000110E80000}'; CLSID_CFormatChm : TGUID = '{23170F69-40C1-278A-1000-000110E90000}'; // chm chi chq chw hxs hxi hxr hxq hxw lit CLSID_CFormatSplit : TGUID = '{23170F69-40C1-278A-1000-000110EA0000}'; // 001 CLSID_CFormatRpm : TGUID = '{23170F69-40C1-278A-1000-000110EB0000}'; // rpm CLSID_CFormatDeb : TGUID = '{23170F69-40C1-278A-1000-000110EC0000}'; // deb CLSID_CFormatCpio : TGUID = '{23170F69-40C1-278A-1000-000110ED0000}'; // cpio CLSID_CFormatTar : TGUID = '{23170F69-40C1-278A-1000-000110EE0000}'; // tar CLSID_CFormatGZip : TGUID = '{23170F69-40C1-278A-1000-000110EF0000}'; // gz gzip tgz tpz implementation const MAXCHECK : int64 = (1 shl 20,',','); ZipCompressionMethod: array[TZipCompressionMethod] of UnicodeString = ('COPY', 'DEFLATE', 'DEFLATE64', 'BZIP2',',','); SevCompressionMethod: array[T7zCompressionMethod] of UnicodeString = ('COPY', 'LZMA', 'BZIP2', 'PPMD', 'DEFLATE', 'DEFLATE64',',','); function DateTimeToFileTime(dt: TDateTime): TFileTime;var st: TSystemTime;begin DateTimeToSystemTime(dt, st,',','); if not (SystemTimeToFileTime(st, Result) and LocalFileTimeToFileTime(Result, Result)) then RaiseLastOSError;end; function FileTimeToDateTime(ft: TFileTime): TDateTime;var st: TSystemTime;begin if not (FileTimeToLocalFileTime(ft, ft) and FileTimeToSystemTime(ft, st)) then RaiseLastOSError; Result := SystemTimeToDateTime(st,',',');end; function CurrentFileTime: TFileTime;begin GetSystemTimeAsFileTime(Result,',',');end; procedure RINOK(const hr: HRESULT,',',');begin if hr <> S_OK then raise Exception.Create(SysErrorMessage(hr),',',');end; procedure SetCardinalProperty(arch: I7zOutArchive; const name: UnicodeString; card: Cardinal,',',');var value: OleVariant;begin TPropVariant(value).vt := VT_UI4; TPropVariant(value).ulVal := card; arch.SetPropertie(name, value,',',');end; procedure SetBooleanProperty(arch: I7zOutArchive; const name: UnicodeString; bool: boolean,',',');begin case bool of true: arch.SetPropertie(name, 'ON',',','); false: arch.SetPropertie(name, 'OFF',',','); end;end; procedure SetCompressionLevel(Arch: I7zOutArchive; level: Cardinal,',',');begin SetCardinalProperty(arch, 'X', level,',',');end; procedure SetMultiThreading(Arch: I7zOutArchive; ThreadCount: Cardinal,',',');begin SetCardinalProperty(arch, 'MT', ThreadCount,',',');end; procedure SetCompressionMethod(Arch: I7zOutArchive; method: TZipCompressionMethod,',',');begin Arch.SetPropertie('M', ZipCompressionMethod[method],',',');end; procedure SetDictionnarySize(Arch: I7zOutArchive; size: Cardinal,',',');begin SetCardinalProperty(arch, 'D', size,',',');end; procedure SetDeflateNumPasses(Arch: I7zOutArchive; pass: Cardinal,',',');begin SetCardinalProperty(arch, 'PASS', pass,',',');end; procedure SetNumFastBytes(Arch: I7zOutArchive; fb: Cardinal,',',');begin SetCardinalProperty(arch, 'FB', fb,',',');end; procedure SetNumMatchFinderCycles(Arch: I7zOutArchive; mc: Cardinal,',',');begin SetCardinalProperty(arch, 'MC', mc,',',');end; procedure SevenZipSetCompressionMethod(Arch: I7zOutArchive; method: T7zCompressionMethod,',',');begin Arch.SetPropertie('0', SevCompressionMethod[method],',',');end; procedure SevenZipSetBindInfo(Arch: I7zOutArchive; const bind: UnicodeString,',',');begin arch.SetPropertie('B', bind,',',');end; procedure SevenZipSetSolidSettings(Arch: I7zOutArchive; solid: boolean,',',');begin SetBooleanProperty(Arch, 'S', solid,',',');end; procedure SevenZipRemoveSfxBlock(Arch: I7zOutArchive; remove: boolean,',',');begin SetBooleanProperty(arch, 'RSFX', remove,',',');end; procedure SevenZipAutoFilter(Arch: I7zOutArchive; auto: boolean,',',');begin SetBooleanProperty(arch, 'F', auto,',',');end; procedure SevenZipCompressHeaders(Arch: I7zOutArchive; compress: boolean,',',');begin SetBooleanProperty(arch, 'HC', compress,',',');end; procedure SevenZipCompressHeadersFull(Arch: I7zOutArchive; compress: boolean,',',');begin SetBooleanProperty(arch, 'HCF', compress,',',');end; procedure SevenZipEncryptHeaders(Arch: I7zOutArchive; Encrypt: boolean,',',');begin SetBooleanProperty(arch, 'HE', Encrypt,',',');end; procedure SevenZipVolumeMode(Arch: I7zOutArchive; Mode: boolean,',',');begin SetBooleanProperty(arch, 'V', Mode,',',');end; type T7zPlugin = class(TInterfacedObject) private FHandle: THandle; FCreateObject: function(const clsid, iid :TGUID; var outObject): HRESULT; stdcall; public constructor Create(const lib: string,',','); virtual; destructor Destroy; override; procedure CreateObject(const clsid, iid :TGUID; var obj,',','); end; T7zCodec = class(T7zPlugin, I7zCodec, ICompressProgressInfo) private FGetMethodProperty: function(index: Cardinal; propID: NMethodPropID; var value: OleVariant): HRESULT; stdcall; FGetNumberOfMethods: function(numMethods: PCardinal): HRESULT; stdcall; function GetNumberOfMethods: Cardinal; function GetMethodProperty(index: Cardinal; propID: NMethodPropID): OleVariant; function GetName(const index: integer): string; protected function SetRatioInfo(inSize, outSize: PInt64): HRESULT; stdcall; public function GetDecoder(const index: integer): ICompressCoder; function GetEncoder(const index: integer): ICompressCoder; constructor Create(const lib: string,',','); override; property MethodProperty[index: Cardinal; propID: NMethodPropID]: OleVariant read GetMethodProperty; property NumberOfMethods: Cardinal read GetNumberOfMethods; property Name[const index: integer]: string read GetName; end; T7zArchive = class(T7zPlugin) private FGetHandlerProperty: function(propID: NArchive; var value: OleVariant): HRESULT; stdcall; FClassId: TGUID; procedure SetClassId(const classid: TGUID,',','); function GetClassId: TGUID; public function GetHandlerProperty(const propID: NArchive): OleVariant; function GetLibStringProperty(const Index: NArchive): string; function GetLibGUIDProperty(const Index: NArchive): TGUID; constructor Create(const lib: string,',','); override; property HandlerProperty[const propID: NArchive]: OleVariant read GetHandlerProperty; property Name: string index kName read GetLibStringProperty; property ClassID: TGUID read GetClassId write SetClassId; property Extension: string index kExtension read GetLibStringProperty; end; T7zInArchive = class(T7zArchive, I7zInArchive, IProgress, IArchiveOpenCallback, IArchiveExtractCallback, ICryptoGetTextPassword, IArchiveOpenVolumeCallback, IArchiveOpenSetSubArchiveName) private FInArchive: IInArchive; FPasswordCallback: T7zPasswordCallback; FPasswordSender: Pointer; FProgressCallback: T7zProgressCallback; FProgressSender: Pointer; FStream: TStream; FPasswordIsDefined: Boolean; FPassword: UnicodeString; FSubArchiveMode: Boolean; FSubArchiveName: UnicodeString; FExtractCallBack: T7zGetStreamCallBack; FExtractSender: Pointer; FExtractPath: string; function GetInArchive: IInArchive; function GetItemProp(const Item: Cardinal; prop: PROPID): OleVariant; protected // I7zInArchive procedure OpenFile(const filename: string,',','); stdcall; procedure OpenStream(stream: IInStream,',','); stdcall; procedure Close; stdcall; function GetNumberOfItems: Cardinal; stdcall; function GetItemPath(const index: integer): UnicodeString; stdcall; function GetItemName(const index: integer): UnicodeString; stdcall; function GetItemSize(const index: integer): Cardinal; stdcall; stdcall; function GetItemIsFolder(const index: integer): boolean; stdcall; procedure ExtractItem(const item: Cardinal; Stream: TStream; test: longbool,',','); stdcall; procedure ExtractItems(items: PCardArray; count: cardinal; test: longbool; sender: pointer; callback: T7zGetStreamCallBack,',','); stdcall; procedure SetPasswordCallback(sender: Pointer; callback: T7zPasswordCallback,',','); stdcall; procedure SetProgressCallback(sender: Pointer; callback: T7zProgressCallback,',','); stdcall; procedure ExtractAll(test: longbool; sender: pointer; callback: T7zGetStreamCallBack,',','); stdcall; procedure ExtractTo(const path: string,',','); stdcall; procedure SetPassword(const password: UnicodeString,',','); stdcall; // IArchiveOpenCallback function SetTotal(files, bytes: PInt64): HRESULT; overload; stdcall; function SetCompleted(files, bytes: PInt64): HRESULT; overload; stdcall; // IProgress function SetTotal(total: Int64): HRESULT; overload; stdcall; function SetCompleted(completeValue: PInt64): HRESULT; overload; stdcall; // IArchiveExtractCallback function GetStream(index: Cardinal; var outStream: ISequentialOutStream; askExtractMode: NAskMode): HRESULT; overload; stdcall; function PrepareOperation(askExtractMode: NAskMode): HRESULT; stdcall; function SetOperationResult(resultEOperationResult: NExtOperationResult): HRESULT; overload; stdcall; // ICryptoGetTextPassword function CryptoGetTextPassword(var password: TBStr): HRESULT; stdcall; // IArchiveOpenVolumeCallback function GetProperty(propID: PROPID; var value: OleVariant): HRESULT; overload; stdcall; function GetStream(const name: PWideChar; var inStream: IInStream): HRESULT; overload; stdcall; // IArchiveOpenSetSubArchiveName function SetSubArchiveName(name: PWideChar): HRESULT; stdcall; public constructor Create(const lib: string,',','); override; destructor Destroy; override; property InArchive: IInArchive read GetInArchive; end; T7zOutArchive = class(T7zArchive, I7zOutArchive, IArchiveUpdateCallback, ICryptoGetTextPassword2) private FOutArchive: IOutArchive; FBatchList: TObjectList; FProgressCallback: T7zProgressCallback; FProgressSender: Pointer; FPassword: UnicodeString; function GetOutArchive: IOutArchive; protected // I7zOutArchive procedure AddStream(Stream: TStream; Ownership: TStreamOwnership; Attributes: Cardinal; CreationTime, LastWriteTime: TFileTime; const Path: UnicodeString; IsFolder, IsAnti: boolean,',','); stdcall; procedure AddFile(const Filename: TFileName; const Path: UnicodeString,',','); stdcall; procedure AddFiles(const Dir, Path, Willcards: string; recurse: boolean,',','); stdcall; procedure SaveToFile(const FileName: TFileName,',','); stdcall; procedure SaveToStream(stream: TStream,',','); stdcall; procedure SetProgressCallback(sender: Pointer; callback: T7zProgressCallback,',','); stdcall; procedure CrearBatch; stdcall; procedure SetPassword(const password: UnicodeString,',','); stdcall; procedure SetPropertie(name: UnicodeString; value: OleVariant,',','); stdcall; // IProgress function SetTotal(total: Int64): HRESULT; stdcall; function SetCompleted(completeValue: PInt64): HRESULT; stdcall; // IArchiveUpdateCallback function GetUpdateItemInfo(index: Cardinal; newData: PInteger; // 1 - new data, 0 - old data newProperties: PInteger; // 1 - new properties, 0 - old properties indexInArchive: PCardinal // -1 if there is no in archive, or if doesn't matter ): HRESULT; stdcall; function GetProperty(index: Cardinal; propID: PROPID; var value: OleVariant): HRESULT; stdcall; function GetStream(index: Cardinal; var inStream: ISequentialInStream): HRESULT; stdcall; function SetOperationResult(operationResult: Integer): HRESULT; stdcall; // ICryptoGetTextPassword2 function CryptoGetTextPassword2(passwordIsDefined: PInteger; var password: TBStr): HRESULT; stdcall; public constructor Create(const lib: string,',','); override; destructor Destroy; override; property OutArchive: IOutArchive read GetOutArchive; end; function CreateInArchive(const classid: TGUID): I7zInArchive;begin Result := T7zInArchive.Create('7z.dll',',','); Result.ClassId := classid;end; function CreateOutArchive(const classid: TGUID): I7zOutArchive;begin Result := T7zOutArchive.Create('7z.dll',',','); Result.ClassId := classid;end; { T7zPlugin } constructor T7zPlugin.Create(const lib: string,',',');begin FHandle := LoadLibrary(PChar(lib),',','); if FHandle = 0 then raise exception.CreateFmt('Error loading library %s', [lib],',','); FCreateObject := GetProcAddress(FHandle, 'CreateObject',',','); if not (Assigned(FCreateObject)) then begin FreeLibrary(FHandle,',','); raise Exception.CreateFmt('%s is not a 7z library', [lib],',','); end;end; destructor T7zPlugin.Destroy;begin FreeLibrary(FHandle,',','); inherited;end; procedure T7zPlugin.CreateObject(const clsid, iid: TGUID; var obj,',',');var hr: HRESULT;begin hr := FCreateObject(clsid, iid, obj,',','); if failed(hr) then raise Exception.Create(SysErrorMessage(hr),',',');end; { T7zCodec } constructor T7zCodec.Create(const lib: string,',',');begin inherited; FGetMethodProperty := GetProcAddress(FHandle, 'GetMethodProperty',',','); FGetNumberOfMethods := GetProcAddress(FHandle, 'GetNumberOfMethods',',','); if not (Assigned(FGetMethodProperty) and Assigned(FGetNumberOfMethods)) then begin FreeLibrary(FHandle,',','); raise Exception.CreateFmt('%s is not a codec library', [lib],',','); end;end; function T7zCodec.GetDecoder(const index: integer): ICompressCoder;var v: OleVariant;begin v := MethodProperty[index, kDecoder]; CreateObject(TPropVariant(v).puuid^, ICompressCoder, Result,',',');end; function T7zCodec.GetEncoder(const index: integer): ICompressCoder;var v: OleVariant;begin v := MethodProperty[index, kEncoder]; CreateObject(TPropVariant(v).puuid^, ICompressCoder, Result,',',');end; function T7zCodec.GetMethodProperty(index: Cardinal; propID: NMethodPropID): OleVariant;var hr: HRESULT;begin hr := FGetMethodProperty(index, propID, Result,',','); if Failed(hr) then raise Exception.Create(SysErrorMessage(hr),',',');end; function T7zCodec.GetName(const index: integer): string;begin Result := MethodProperty[index, kName_];end; function T7zCodec.GetNumberOfMethods: Cardinal;var hr: HRESULT;begin hr := FGetNumberOfMethods(@Result,',','); if Failed(hr) then raise Exception.Create(SysErrorMessage(hr),',',');end; function T7zCodec.SetRatioInfo(inSize, outSize: PInt64): HRESULT;begin Result := S_OK;end; { T7zInArchive } procedure T7zInArchive.Close; stdcall;begin FPasswordIsDefined := false; FSubArchiveMode := false; FInArchive.Close; FInArchive := nil;end; constructor T7zInArchive.Create(const lib: string,',',');begin inherited; FPasswordCallback := nil; FPasswordSender := nil; FPasswordIsDefined := false; FSubArchiveMode := false; FExtractCallBack := nil; FExtractSender := nil;end; destructor T7zInArchive.Destroy;begin FInArchive := nil; inherited;end; function T7zInArchive.GetInArchive: IInArchive;begin if FInArchive = nil then CreateObject(ClassID, IInArchive, FInArchive,',','); Result := FInArchive;end; function T7zInArchive.GetItemPath(const index: integer): UnicodeString; stdcall;begin Result := UnicodeString(GetItemProp(index, kpidPath),',',');end; function T7zInArchive.GetNumberOfItems: Cardinal; stdcall;begin RINOK(FInArchive.GetNumberOfItems(Result),',',');end; procedure T7zInArchive.OpenFile(const filename: string,',','); stdcall;var strm: IInStream;begin strm := T7zStream.Create(TFileStream.Create(filename, fmOpenRead or fmShareDenyNone), soOwned,',','); try RINOK( InArchive.Open( strm, @MAXCHECK, self as IArchiveOpenCallBack ) ,',','); finally strm := nil; end;end; procedure T7zInArchive.OpenStream(stream: IInStream,',','); stdcall;begin RINOK(InArchive.Open(stream, @MAXCHECK, self as IArchiveOpenCallBack),',',');end; function T7zInArchive.GetItemIsFolder(const index: integer): boolean; stdcall;begin Result := Boolean(GetItemProp(index, kpidIsFolder),',',');end; function T7zInArchive.GetItemProp(const Item: Cardinal; prop: PROPID): OleVariant;begin FInArchive.GetProperty(Item, prop, Result,',',');end; procedure T7zInArchive.ExtractItem(const item: Cardinal; Stream: TStream; test: longbool,',','); stdcall;begin FStream := Stream; try if test then RINOK(FInArchive.Extract(@item, 1, 1, self as IArchiveExtractCallback)) else RINOK(FInArchive.Extract(@item, 1, 0, self as IArchiveExtractCallback),',','); finally FStream := nil; end;end; function T7zInArchive.GetStream(index: Cardinal; var outStream: ISequentialOutStream; askExtractMode: NAskMode): HRESULT;var path: string;begin if askExtractMode = kExtract then if FStream <> nil then outStream := T7zStream.Create(FStream, soReference) as ISequentialOutStream else if assigned(FExtractCallback) then begin Result := FExtractCallBack(FExtractSender, index, outStream,',','); Exit; end else if FExtractPath <> '' then begin if not GetItemIsFolder(index) then begin path := FExtractPath + GetItemPath(index,',','); ForceDirectories(ExtractFilePath(path),',','); outStream := T7zStream.Create(TFileStream.Create(path, fmCreate), soOwned,',','); end; end; Result := S_OK;end; function T7zInArchive.PrepareOperation(askExtractMode: NAskMode): HRESULT;begin Result := S_OK;end; function T7zInArchive.SetCompleted(completeValue: PInt64): HRESULT;begin if Assigned(FProgressCallback) and (completeValue <> nil) then Result := FProgressCallback(FProgressSender, false, completeValue^) else Result := S_OK;end; function T7zInArchive.SetCompleted(files, bytes: PInt64): HRESULT;begin Result := S_OK;end; function T7zInArchive.SetOperationResult( resultEOperationResult: NExtOperationResult): HRESULT;begin Result := S_OK;end; function T7zInArchive.SetTotal(total: Int64): HRESULT;begin if Assigned(FProgressCallback) then Result := FProgressCallback(FProgressSender, true, total) else Result := S_OK;end; function T7zInArchive.SetTotal(files, bytes: PInt64): HRESULT;begin Result := S_OK;end; function T7zInArchive.CryptoGetTextPassword(var password: TBStr): HRESULT;var wpass: UnicodeString;begin if FPasswordIsDefined then begin password := SysAllocString(PWideChar(FPassword),',','); Result := S_OK; end else if Assigned(FPasswordCallback) then begin Result := FPasswordCallBack(FPasswordSender, wpass,',','); if Result = S_OK then begin password := SysAllocString(PWideChar(wpass),',','); FPasswordIsDefined := True; FPassword := wpass; end; end else Result := S_FALSE;end; function T7zInArchive.GetProperty(propID: PROPID; var value: OleVariant): HRESULT;begin Result := S_OK;end; function T7zInArchive.GetStream(const name: PWideChar; var inStream: IInStream): HRESULT;begin Result := S_OK;end; procedure T7zInArchive.SetPasswordCallback(sender: Pointer; callback: T7zPasswordCallback,',','); stdcall;begin FPasswordSender := sender; FPasswordCallback := callback;end; function T7zInArchive.SetSubArchiveName(name: PWideChar): HRESULT;begin FSubArchiveMode := true; FSubArchiveName := name; Result := S_OK;end; function T7zInArchive.GetItemName(const index: integer): UnicodeString; stdcall;begin Result := UnicodeString(GetItemProp(index, kpidName),',',');end; function T7zInArchive.GetItemSize(const index: integer): Cardinal; stdcall;begin Result := Cardinal(GetItemProp(index, kpidSize),',',');end; procedure T7zInArchive.ExtractItems(items: PCardArray; count: cardinal; test: longbool; sender: pointer; callback: T7zGetStreamCallBack,',','); stdcall;begin FExtractCallBack := callback; FExtractSender := sender; try if test then RINOK(FInArchive.Extract(items, count, 1, self as IArchiveExtractCallback)) else RINOK(FInArchive.Extract(items, count, 0, self as IArchiveExtractCallback),',','); finally FExtractCallBack := nil; FExtractSender := nil; end;end; procedure T7zInArchive.SetProgressCallback(sender: Pointer; callback: T7zProgressCallback,',','); stdcall;begin FProgressSender := sender; FProgressCallback := callback;end; procedure T7zInArchive.ExtractAll(test: longbool; sender: pointer; callback: T7zGetStreamCallBack,',',');begin FExtractCallBack := callback; FExtractSender := sender; try if test then RINOK(FInArchive.Extract(nil, $FFFFFFFF, 1, self as IArchiveExtractCallback)) else RINOK(FInArchive.Extract(nil, $FFFFFFFF, 0, self as IArchiveExtractCallback),',','); finally FExtractCallBack := nil; FExtractSender := nil; end;end; procedure T7zInArchive.ExtractTo(const path: string,',',');begin FExtractPath := IncludeTrailingPathDelimiter(path,',','); try RINOK(FInArchive.Extract(nil, $FFFFFFFF, 0, self as IArchiveExtractCallback),',','); finally FExtractPath := ''; end;end; procedure T7zInArchive.SetPassword(const password: UnicodeString,',',');begin FPassword := password; FPasswordIsDefined := FPassword <> '';end; { T7zArchive } constructor T7zArchive.Create(const lib: string,',',');begin inherited; FGetHandlerProperty := GetProcAddress(FHandle, 'GetHandlerProperty',',','); if not Assigned(FGetHandlerProperty) then begin FreeLibrary(FHandle,',','); raise Exception.CreateFmt('%s is not a Format library', [lib],',','); end; FClassId := GUID_NULL;end; function T7zArchive.GetClassId: TGUID;begin Result := FClassId;end; function T7zArchive.GetHandlerProperty(const propID: NArchive): OleVariant;var hr: HRESULT;begin hr := FGetHandlerProperty(propID, Result,',','); if Failed(hr) then raise Exception.Create(SysErrorMessage(hr),',',');end; function T7zArchive.GetLibGUIDProperty(const Index: NArchive): TGUID;var v: OleVariant;begin v := HandlerProperty[index]; Result := TPropVariant(v).puuid^;end; function T7zArchive.GetLibStringProperty(const Index: NArchive): string;begin Result := HandlerProperty[Index];end; procedure T7zArchive.SetClassId(const classid: TGUID,',',');begin FClassId := classid;end; { T7zStream } constructor T7zStream.Create(Stream: TStream; Ownership: TStreamOwnership,',',');begin inherited Create; FStream := Stream; FOwnership := Ownership;end; destructor T7zStream.destroy;begin if FOwnership = soOwned then begin FStream.Free; FStream := nil; end; inherited;end; function T7zStream.Flush: HRESULT;begin Result := S_OK;end; function T7zStream.GetSize(size: PInt64): HRESULT;begin if size <> nil then size^ := FStream.Size; Result := S_OK;end; function T7zStream.Read(data: Pointer; size: Cardinal; processedSize: PCardinal): HRESULT;var len: integer;begin len := FStream.Read(data^, size,',','); if processedSize <> nil then processedSize^ := len; Result := S_OK;end; function T7zStream.Seek(offset: Int64; seekOrigin: Cardinal; newPosition: PInt64): HRESULT;begin FStream.Seek(offset, TSeekOrigin(seekOrigin),',','); if newPosition <> nil then newPosition^ := FStream.Position; Result := S_OK;end; function T7zStream.SetSize(newSize: Int64): HRESULT;begin FStream.Size := newSize; Result := S_OK;end; function T7zStream.Write(data: Pointer; size: Cardinal; processedSize: PCardinal): HRESULT;var len: integer;begin len := FStream.Write(data^, size,',','); if processedSize <> nil then processedSize^ := len; Result := S_OK;end; type TSourceMode = (smStream, smFile,',','); T7zBatchItem = class SourceMode: TSourceMode; Stream: TStream; Attributes: Cardinal; CreationTime, LastWriteTime: TFileTime; Path: UnicodeString; IsFolder, IsAnti: boolean; FileName: TFileName; Ownership: TStreamOwnership; Size: Cardinal; destructor Destroy; override; end; destructor T7zBatchItem.Destroy;begin if (Ownership = soOwned) and (Stream <> nil) then Stream.Free; inherited;end; { T7zOutArchive } procedure T7zOutArchive.AddFile(const Filename: TFileName; const Path: UnicodeString,',',');var item: T7zBatchItem; Handle: THandle;begin if not FileExists(Filename) then exit; item := T7zBatchItem.Create; Item.SourceMode := smFile; item.Stream := nil; item.FileName := Filename; item.Path := Path; Handle := FileOpen(Filename, fmOpenRead or fmShareDenyNone,',','); GetFileTime(Handle, @item.CreationTime, nil, @item.LastWriteTime,',','); item.Size := GetFileSize(Handle, nil,',','); CloseHandle(Handle,',','); item.Attributes := GetFileAttributes(PChar(Filename),',','); item.IsFolder := false; item.IsAnti := False; item.Ownership := soOwned; FBatchList.Add(item,',',');end; procedure T7zOutArchive.AddFiles(const Dir, Path, Willcards: string; recurse: boolean,',',');var lencut: integer; willlist: TStringList; zedir: string; procedure Traverse(p: string,',','); var f: TSearchRec; i: integer; item: T7zBatchItem; begin if recurse then begin if FindFirst(p + '*.*', faDirectory, f) = 0 then repeat if (f.Name[1] <> '.') then Traverse(IncludeTrailingPathDelimiter(p + f.Name),',','); until FindNext(f) <> 0; SysUtils.FindClose(f,',','); end; for i := 0 to willlist.Count - 1 do begin if FindFirst(p + willlist, faReadOnly or faHidden or faSysFile or faArchive, f) = 0 then repeat item := T7zBatchItem.Create; Item.SourceMode := smFile; item.Stream := nil; item.FileName := p + f.Name; item.Path := copy(item.FileName, lencut, length(item.FileName) - lencut + 1,',','); if path <> '' then item.Path := IncludeTrailingPathDelimiter(path) + item.Path; item.CreationTime := f.FindData.ftCreationTime; item.LastWriteTime := f.FindData.ftLastWriteTime; item.Attributes := f.FindData.dwFileAttributes; item.Size := f.Size; item.IsFolder := false; item.IsAnti := False; item.Ownership := soOwned; FBatchList.Add(item,',','); until FindNext(f) <> 0; SysUtils.FindClose(f,',','); end; end;begin willlist := TStringList.Create; try willlist.Delimiter := ';'; willlist.DelimitedText := Willcards; zedir := IncludeTrailingPathDelimiter(Dir,',','); lencut := Length(zedir) + 1; Traverse(zedir,',','); finally willlist.Free; end;end; procedure T7zOutArchive.AddStream(Stream: TStream; Ownership: TStreamOwnership; Attributes: Cardinal; CreationTime, LastWriteTime: TFileTime; const Path: UnicodeString; IsFolder, IsAnti: boolean,',','); stdcall;var item: T7zBatchItem;begin item := T7zBatchItem.Create; Item.SourceMode := smStream; item.Attributes := Attributes; item.CreationTime := CreationTime; item.LastWriteTime := LastWriteTime; item.Path := Path; item.IsFolder := IsFolder; item.IsAnti := IsAnti; item.Stream := Stream; item.Size := Stream.Size; item.Ownership := Ownership; FBatchList.Add(item,',',');end; procedure T7zOutArchive.CrearBatch;begin FBatchList.Clear;end; constructor T7zOutArchive.Create(const lib: string,',',');begin inherited; FBatchList := TObjectList.Create; FProgressCallback := nil; FProgressSender := nil;end; function T7zOutArchive.CryptoGetTextPassword2(passwordIsDefined: PInteger; var password: TBStr): HRESULT;begin if FPassword <> '' then begin passwordIsDefined^ := 1; password := SysAllocString(PWideChar(FPassword),',','); end else passwordIsDefined^ := 0; Result := S_OK;end; destructor T7zOutArchive.Destroy;begin FOutArchive := nil; FBatchList.Free; inherited;end; function T7zOutArchive.GetOutArchive: IOutArchive;begin if FOutArchive = nil then CreateObject(ClassID, IOutArchive, FOutArchive,',','); Result := FOutArchive;end; function T7zOutArchive.GetProperty(index: Cardinal; propID: PROPID; var value: OleVariant): HRESULT;var item: T7zBatchItem;begin item := T7zBatchItem(FBatchList[index],',','); case propID of kpidAttributes: begin TPropVariant(Value).vt := VT_UI4; TPropVariant(Value).ulVal := item.Attributes; end; kpidLastWriteTime: begin TPropVariant(value).vt := VT_FILETIME; TPropVariant(value).filetime := item.LastWriteTime; end; kpidPath: begin if item.Path <> '' then value := item.Path; end; kpidIsFolder: Value := item.IsFolder; kpidSize: begin TPropVariant(Value).vt := VT_UI8; TPropVariant(Value).uhVal.QuadPart := item.Size; end; kpidCreationTime: begin TPropVariant(value).vt := VT_FILETIME; TPropVariant(value).filetime := item.CreationTime; end; kpidIsAnti: value := item.IsAnti; else // beep(0,0,',','); end; Result := S_OK;end; function T7zOutArchive.GetStream(index: Cardinal; var inStream: ISequentialInStream): HRESULT;var item: T7zBatchItem;begin item := T7zBatchItem(FBatchList[index],',','); case item.SourceMode of smFile: inStream := T7zStream.Create(TFileStream.Create(item.FileName, fmOpenRead or fmShareDenyNone), soOwned,',','); smStream: begin item.Stream.Seek(0, soFromBeginning,',','); inStream := T7zStream.Create(item.Stream,',','); end; end; Result := S_OK;end; function T7zOutArchive.GetUpdateItemInfo(index: Cardinal; newData, newProperties: PInteger; indexInArchive: PCardinal): HRESULT;begin newData^ := 1; newProperties^ := 1; indexInArchive^ := CArdinal(-1,',','); Result := S_OK;end; procedure T7zOutArchive.SaveToFile(const FileName: TFileName,',',');var f: TFileStream;begin f := TFileStream.Create(FileName, fmCreate,',','); try SaveToStream(f,',','); finally f.free; end;end; procedure T7zOutArchive.SaveToStream(stream: TStream,',',');var strm: ISequentialOutStream;begin strm := T7zStream.Create(stream,',','); try RINOK(OutArchive.UpdateItems(strm, FBatchList.Count, self as IArchiveUpdateCallback),',','); finally strm := nil; end;end; function T7zOutArchive.SetCompleted(completeValue: PInt64): HRESULT;begin if Assigned(FProgressCallback) and (completeValue <> nil) then Result := FProgressCallback(FProgressSender, false, completeValue^) else Result := S_OK;end; function T7zOutArchive.SetOperationResult( operationResult: Integer): HRESULT;begin Result := S_OK;end; procedure T7zOutArchive.SetPassword(const password: UnicodeString,',',');begin FPassword := password;end; procedure T7zOutArchive.SetProgressCallback(sender: Pointer; callback: T7zProgressCallback,',',');begin FProgressCallback := callback; FProgressSender := sender;end; procedure T7zOutArchive.SetPropertie(name: UnicodeString; value: OleVariant,',',');var intf: ISetProperties; p: PWideChar;begin intf := OutArchive as ISetProperties; p := PWideChar(name,',','); RINOK(intf.SetProperties(@p, @TPropVariant(value), 1),',',');end; function T7zOutArchive.SetTotal(total: Int64): HRESULT;begin if Assigned(FProgressCallback) then Result := FProgressCallback(FProgressSender, true, total) else Result := S_OK;end; end.
关键字词: