【Delphi】从内存读取或解压压缩文件(RAR、ZIP、TAR、GZIP等)(三)

该博客介绍了如何利用Delphi编程从内存中读取和解压各种类型的压缩文件,包括RAR、ZIP、TAR和GZIP。作者提供了sevenzip.pas的源码片段,并分享了相关资源链接。
摘要由CSDN通过智能技术生成

续上章

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 <<a href="mailto:hgourvest@gmail.com">hgourvest@gmail.com</a>> *)
(* V1.2 *)
(* ****************************************************************************** *)
unit sevenzip;
{$ALIGN ON}
{$MINENUMSIZE 4}
{$WARN SYMBOL_PLATFORM OFF}
    
interface
    
uses 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"
  // *************************************************
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值