Source code

Revision control

Copy as Markdown

Other Tools

// LoadCodecs.h↩
#ifndef __LOAD_CODECS_H↩
#define __LOAD_CODECS_H↩
/*↩
Client application uses LoadCodecs.* to load plugins to↩
CCodecs object, that contains 3 lists of plugins:↩
1) Formats - internal and external archive handlers↩
2) Codecs - external codecs↩
3) Hashers - external hashers↩
EXTERNAL_CODECS↩
---------------↩
if EXTERNAL_CODECS is defined, then the code tries to load external↩
plugins from DLL files (shared libraries).↩
There are two types of executables in 7-Zip:↩
1) Executable that uses external plugins must be compiled↩
with EXTERNAL_CODECS defined:↩
- 7z.exe, 7zG.exe, 7zFM.exe↩
Note: EXTERNAL_CODECS is used also in CPP/7zip/Common/CreateCoder.h↩
that code is used in plugin module (7z.dll).↩
2) Standalone modules are compiled without EXTERNAL_CODECS:↩
- SFX modules: 7z.sfx, 7zCon.sfx↩
- standalone versions of console 7-Zip: 7za.exe, 7zr.exe↩
if EXTERNAL_CODECS is defined, CCodecs class implements interfaces:↩
- ICompressCodecsInfo : for Codecs↩
- IHashers : for Hashers↩
The client application can send CCodecs object to each plugin module.↩
And plugin module can use ICompressCodecsInfo or IHashers interface to access↩
another plugins.↩
There are 2 ways to send (ICompressCodecsInfo * compressCodecsInfo) to plugin↩
1) for old versions:↩
a) request ISetCompressCodecsInfo from created archive handler.↩
b) call ISetCompressCodecsInfo::SetCompressCodecsInfo(compressCodecsInfo)↩
2) for new versions:↩
a) request "SetCodecs" function from DLL file↩
b) call SetCodecs(compressCodecsInfo) function from DLL file↩
*/
#include "../../../Common/MyBuffer.h"
#include "../../../Common/MyCom.h"
#include "../../../Common/MyString.h"
#include "../../../Common/ComTry.h"
#ifdef EXTERNAL_CODECS↩
#include "../../../Windows/DLL.h"
#endif
#include "../../ICoder.h"
#include "../../Archive/IArchive.h"
#ifdef EXTERNAL_CODECS↩
struct CDllCodecInfo↩
{↩
unsigned LibIndex;↩
UInt32 CodecIndex;↩
bool EncoderIsAssigned;↩
bool DecoderIsAssigned;↩
CLSID Encoder;↩
CLSID Decoder;↩
};↩
struct CDllHasherInfo↩
{↩
unsigned LibIndex;↩
UInt32 HasherIndex;↩
};↩
#endif
struct CArcExtInfo↩
{↩
UString Ext;↩
UString AddExt;↩
CArcExtInfo() {}↩
CArcExtInfo(const UString &ext): Ext(ext) {}↩
CArcExtInfo(const UString &ext, const UString &addExt): Ext(ext), AddExt(addExt) {}↩
};↩
struct CArcInfoEx↩
{↩
UInt32 Flags;↩
Func_CreateInArchive CreateInArchive;↩
Func_IsArc IsArcFunc;↩
UString Name;↩
CObjectVector<CArcExtInfo> Exts;↩
#ifndef _SFX↩
Func_CreateOutArchive CreateOutArchive;↩
bool UpdateEnabled;↩
bool NewInterface;↩
// UInt32 Version;↩
UInt32 SignatureOffset;↩
CObjectVector<CByteBuffer> Signatures;↩
#ifdef NEW_FOLDER_INTERFACE↩
UStringVector AssociateExts;↩
#endif
#endif
#ifdef EXTERNAL_CODECS↩
int LibIndex;↩
UInt32 FormatIndex;↩
CLSID ClassID;↩
#endif
bool Flags_KeepName() const { return (Flags & NArcInfoFlags::kKeepName) != 0; }↩
bool Flags_FindSignature() const { return (Flags & NArcInfoFlags::kFindSignature) != 0; }↩
bool Flags_AltStreams() const { return (Flags & NArcInfoFlags::kAltStreams) != 0; }↩
bool Flags_NtSecure() const { return (Flags & NArcInfoFlags::kNtSecure) != 0; }↩
bool Flags_SymLinks() const { return (Flags & NArcInfoFlags::kSymLinks) != 0; }↩
bool Flags_HardLinks() const { return (Flags & NArcInfoFlags::kHardLinks) != 0; }↩
bool Flags_UseGlobalOffset() const { return (Flags & NArcInfoFlags::kUseGlobalOffset) != 0; }↩
bool Flags_StartOpen() const { return (Flags & NArcInfoFlags::kStartOpen) != 0; }↩
bool Flags_BackwardOpen() const { return (Flags & NArcInfoFlags::kBackwardOpen) != 0; }↩
bool Flags_PreArc() const { return (Flags & NArcInfoFlags::kPreArc) != 0; }↩
bool Flags_PureStartOpen() const { return (Flags & NArcInfoFlags::kPureStartOpen) != 0; }↩
UString GetMainExt() const
{↩
if (Exts.IsEmpty())↩
return UString();↩
return Exts[0].Ext;↩
}↩
int FindExtension(const UString &ext) const;↩
/*↩
UString GetAllExtensions() const↩
{↩
UString s;↩
for (int i = 0; i < Exts.Size(); i++)↩
{↩
if (i > 0)↩
s += ' ';↩
s += Exts[i].Ext;↩
}↩
return s;↩
}↩
*/
void AddExts(const UString &ext, const UString &addExt);↩
bool IsSplit() const { return StringsAreEqualNoCase_Ascii(Name, "Split"); }↩
// bool IsRar() const { return StringsAreEqualNoCase_Ascii(Name, "Rar"); }↩
CArcInfoEx():↩
Flags(0),↩
CreateInArchive(NULL),↩
IsArcFunc(NULL)↩
#ifndef _SFX↩
, CreateOutArchive(NULL)↩
, UpdateEnabled(false)↩
, NewInterface(false)↩
// , Version(0)↩
, SignatureOffset(0)↩
#endif
#ifdef EXTERNAL_CODECS↩
, LibIndex(-1)↩
#endif
{}↩
};↩
#ifdef NEW_FOLDER_INTERFACE↩
struct CCodecIcons↩
{↩
struct CIconPair↩
{↩
UString Ext;↩
int IconIndex;↩
};↩
CObjectVector<CIconPair> IconPairs;↩
void LoadIcons(HMODULE m);↩
bool FindIconIndex(const UString &ext, int &iconIndex) const;↩
};↩
#endif
#ifdef EXTERNAL_CODECS↩
struct CCodecLib↩
#ifdef NEW_FOLDER_INTERFACE↩
: public CCodecIcons↩
#endif
{↩
NWindows::NDLL::CLibrary Lib;↩
FString Path;↩
Func_CreateObject CreateObject;↩
Func_GetMethodProperty GetMethodProperty;↩
Func_CreateDecoder CreateDecoder;↩
Func_CreateEncoder CreateEncoder;↩
Func_SetCodecs SetCodecs;↩
CMyComPtr<IHashers> ComHashers;↩
#ifdef NEW_FOLDER_INTERFACE↩
void LoadIcons() { CCodecIcons::LoadIcons((HMODULE)Lib); }↩
#endif
CCodecLib():↩
CreateObject(NULL),↩
GetMethodProperty(NULL),↩
CreateDecoder(NULL),↩
CreateEncoder(NULL),↩
SetCodecs(NULL)↩
{}↩
};↩
#endif
class CCodecs:↩
#ifdef EXTERNAL_CODECS↩
public ICompressCodecsInfo,↩
public IHashers,↩
#else
public IUnknown,↩
#endif
public CMyUnknownImp↩
{↩
CLASS_NO_COPY(CCodecs);↩
public:↩
#ifdef EXTERNAL_CODECS↩
CObjectVector<CCodecLib> Libs;↩
FString MainDll_ErrorPath;↩
void CloseLibs();↩
class CReleaser↩
{↩
CLASS_NO_COPY(CReleaser);↩
/* CCodecsReleaser object releases CCodecs links.↩
1) CCodecs is COM object that is deleted when all links to that object will be released/↩
2) CCodecs::Libs[i] can hold (ICompressCodecsInfo *) link to CCodecs object itself.↩
To break that reference loop, we must close all CCodecs::Libs in CCodecsReleaser desttructor. */
CCodecs *_codecs;↩
public:↩
CReleaser(): _codecs(NULL) {}↩
void Set(CCodecs *codecs) { _codecs = codecs; }↩
~CReleaser() { if (_codecs) _codecs->CloseLibs(); }↩
};↩
bool NeedSetLibCodecs; // = false, if we don't need to set codecs for archive handler via ISetCompressCodecsInfo↩
HRESULT LoadCodecs();↩
HRESULT LoadFormats();↩
HRESULT LoadDll(const FString &path, bool needCheckDll, bool *loadedOK = NULL);↩
HRESULT LoadDllsFromFolder(const FString &folderPrefix);↩
HRESULT CreateArchiveHandler(const CArcInfoEx &ai, bool outHandler, void **archive) const
{↩
return Libs[ai.LibIndex].CreateObject(&ai.ClassID, outHandler ? &IID_IOutArchive : &IID_IInArchive, (void **)archive);↩
}↩
#endif
#ifdef NEW_FOLDER_INTERFACE↩
CCodecIcons InternalIcons;↩
#endif
CObjectVector<CArcInfoEx> Formats;↩
#ifdef EXTERNAL_CODECS↩
CRecordVector<CDllCodecInfo> Codecs;↩
CRecordVector<CDllHasherInfo> Hashers;↩
#endif
bool CaseSensitiveChange;↩
bool CaseSensitive;↩
CCodecs():↩
#ifdef EXTERNAL_CODECS↩
NeedSetLibCodecs(true),↩
#endif
CaseSensitiveChange(false),↩
CaseSensitive(false)↩
{}↩
~CCodecs()↩
{↩
// OutputDebugStringA("~CCodecs");↩
}↩
const wchar_t *GetFormatNamePtr(int formatIndex) const
{↩
return formatIndex < 0 ? L"#" : (const wchar_t *)Formats[formatIndex].Name;↩
}↩
HRESULT Load();↩
#ifndef _SFX↩
int FindFormatForArchiveName(const UString &arcPath) const;↩
int FindFormatForExtension(const UString &ext) const;↩
int FindFormatForArchiveType(const UString &arcType) const;↩
bool FindFormatForArchiveType(const UString &arcType, CIntVector &formatIndices) const;↩
#endif
#ifdef EXTERNAL_CODECS↩
MY_UNKNOWN_IMP2(ICompressCodecsInfo, IHashers)↩
STDMETHOD(GetNumMethods)(UInt32 *numMethods);↩
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);↩
STDMETHOD(CreateDecoder)(UInt32 index, const GUID *iid, void **coder);↩
STDMETHOD(CreateEncoder)(UInt32 index, const GUID *iid, void **coder);↩
STDMETHOD_(UInt32, GetNumHashers)();↩
STDMETHOD(GetHasherProp)(UInt32 index, PROPID propID, PROPVARIANT *value);↩
STDMETHOD(CreateHasher)(UInt32 index, IHasher **hasher);↩
#else
MY_UNKNOWN_IMP↩
#endif // EXTERNAL_CODECS↩
#ifdef EXTERNAL_CODECS↩
int GetCodec_LibIndex(UInt32 index) const;↩
bool GetCodec_DecoderIsAssigned(UInt32 index) const;↩
bool GetCodec_EncoderIsAssigned(UInt32 index) const;↩
UInt32 GetCodec_NumStreams(UInt32 index);↩
HRESULT GetCodec_Id(UInt32 index, UInt64 &id);↩
AString GetCodec_Name(UInt32 index);↩
int GetHasherLibIndex(UInt32 index);↩
UInt64 GetHasherId(UInt32 index);↩
AString GetHasherName(UInt32 index);↩
UInt32 GetHasherDigestSize(UInt32 index);↩
#endif
HRESULT CreateInArchive(unsigned formatIndex, CMyComPtr<IInArchive> &archive) const
{↩
const CArcInfoEx &ai = Formats[formatIndex];↩
#ifdef EXTERNAL_CODECS↩
if (ai.LibIndex < 0)↩
#endif
{↩
COM_TRY_BEGIN↩
archive = ai.CreateInArchive();↩
return S_OK;↩
COM_TRY_END↩
}↩
#ifdef EXTERNAL_CODECS↩
return CreateArchiveHandler(ai, false, (void **)&archive);↩
#endif
}↩
#ifndef _SFX↩
HRESULT CreateOutArchive(unsigned formatIndex, CMyComPtr<IOutArchive> &archive) const
{↩
const CArcInfoEx &ai = Formats[formatIndex];↩
#ifdef EXTERNAL_CODECS↩
if (ai.LibIndex < 0)↩
#endif
{↩
COM_TRY_BEGIN↩
archive = ai.CreateOutArchive();↩
return S_OK;↩
COM_TRY_END↩
}↩
#ifdef EXTERNAL_CODECS↩
return CreateArchiveHandler(ai, true, (void **)&archive);↩
#endif
}↩
int FindOutFormatFromName(const UString &name) const
{↩
FOR_VECTOR (i, Formats)↩
{↩
const CArcInfoEx &arc = Formats[i];↩
if (!arc.UpdateEnabled)↩
continue;↩
if (arc.Name.IsEqualTo_NoCase(name))↩
return i;↩
}↩
return -1;↩
}↩
#endif // _SFX↩
};↩
#ifdef EXTERNAL_CODECS↩
#define CREATE_CODECS_OBJECT \↩
CCodecs *codecs = new CCodecs; \↩
CExternalCodecs __externalCodecs; \↩
__externalCodecs.GetCodecs = codecs; \↩
__externalCodecs.GetHashers = codecs; \↩
CCodecs::CReleaser codecsReleaser; \↩
codecsReleaser.Set(codecs);↩
#else
#define CREATE_CODECS_OBJECT \↩
CCodecs *codecs = new CCodecs; \↩
CMyComPtr<IUnknown> __codecsRef = codecs;↩
#endif
#endif