This commit is contained in:
Igor Pavlov
2015-06-15 00:00:00 +00:00
committed by Kornel Lesiński
parent 0713a3ab80
commit 54490d51d5
591 changed files with 34932 additions and 16390 deletions

View File

@@ -3,34 +3,82 @@
#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"
#include "../../ICoder.h"
#ifdef EXTERNAL_CODECS
#include "../../../Windows/DLL.h"
#endif
#include "../../ICoder.h"
#include "../../Archive/IArchive.h"
#ifdef EXTERNAL_CODECS
struct CDllCodecInfo
{
CLSID Encoder;
CLSID Decoder;
unsigned LibIndex;
UInt32 CodecIndex;
bool EncoderIsAssigned;
bool DecoderIsAssigned;
int LibIndex;
UInt32 CodecIndex;
CLSID Encoder;
CLSID Decoder;
};
struct CDllHasherInfo
{
int LibIndex;
unsigned LibIndex;
UInt32 HasherIndex;
};
#include "../../Archive/IArchive.h"
#endif
struct CArcExtInfo
{
@@ -129,9 +177,8 @@ struct CArcInfoEx
{}
};
#ifdef EXTERNAL_CODECS
#ifdef NEW_FOLDER_INTERFACE
struct CCodecIcons
{
struct CIconPair
@@ -140,11 +187,15 @@ struct CCodecIcons
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
@@ -152,56 +203,108 @@ struct CCodecLib
{
NWindows::NDLL::CLibrary Lib;
FString Path;
Func_GetMethodProperty GetMethodProperty;
Func_CreateObject CreateObject;
CMyComPtr<IHashers> Hashers;
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(): GetMethodProperty(NULL) {}
CCodecLib():
CreateObject(NULL),
GetMethodProperty(NULL),
CreateDecoder(NULL),
CreateEncoder(NULL),
SetCodecs(NULL)
{}
};
#endif
class CCodecs:
#ifdef EXTERNAL_CODECS
public ICompressCodecsInfo,
public IHashers,
public ICompressCodecsInfo,
public IHashers,
#else
public IUnknown,
public IUnknown,
#endif
public CMyUnknownImp
{
CLASS_NO_COPY(CCodecs);
public:
#ifdef EXTERNAL_CODECS
CObjectVector<CCodecLib> Libs;
CRecordVector<CDllCodecInfo> Codecs;
CRecordVector<CDllHasherInfo> Hashers;
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
HRESULT LoadCodecs();
HRESULT LoadFormats();
HRESULT LoadDll(const FString &path, bool needCheckDll);
HRESULT LoadDllsFromFolder(const FString &folderPrefix);
HRESULT CreateArchiveHandler(const CArcInfoEx &ai, void **archive, bool outHandler) const
{
return Libs[ai.LibIndex].CreateObject(&ai.ClassID, outHandler ? &IID_IOutArchive : &IID_IInArchive, (void **)archive);
}
CObjectVector<CArcInfoEx> Formats;
#ifdef EXTERNAL_CODECS
CRecordVector<CDllCodecInfo> Codecs;
CRecordVector<CDllHasherInfo> Hashers;
#endif
public:
CObjectVector<CArcInfoEx> Formats;
bool CaseSensitiveChange;
bool CaseSensitive;
CCodecs(): CaseSensitiveChange(false), CaseSensitive(false) {}
CCodecs():
#ifdef EXTERNAL_CODECS
NeedSetLibCodecs(true),
#endif
CaseSensitiveChange(false),
CaseSensitive(false)
{}
~CCodecs()
{
// OutputDebugStringA("~CCodecs");
}
const wchar_t *GetFormatNamePtr(int formatIndex)
const wchar_t *GetFormatNamePtr(int formatIndex) const
{
return formatIndex < 0 ? L"#" : (const wchar_t *)Formats[formatIndex].Name;
}
@@ -219,10 +322,10 @@ public:
MY_UNKNOWN_IMP2(ICompressCodecsInfo, IHashers)
STDMETHOD(GetNumberOfMethods)(UInt32 *numMethods);
STDMETHOD(GetNumMethods)(UInt32 *numMethods);
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
STDMETHOD(CreateDecoder)(UInt32 index, const GUID *interfaceID, void **coder);
STDMETHOD(CreateEncoder)(UInt32 index, const GUID *interfaceID, void **coder);
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);
@@ -234,16 +337,19 @@ public:
#endif // EXTERNAL_CODECS
#ifdef EXTERNAL_CODECS
int GetCodecLibIndex(UInt32 index);
bool GetCodecEncoderIsAssigned(UInt32 index);
HRESULT GetCodecId(UInt32 index, UInt64 &id);
UString GetCodecName(UInt32 index);
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);
UString GetHasherName(UInt32 index);
AString GetHasherName(UInt32 index);
UInt32 GetHasherDigestSize(UInt32 index);
#endif
@@ -261,7 +367,7 @@ public:
COM_TRY_END
}
#ifdef EXTERNAL_CODECS
return CreateArchiveHandler(ai, (void **)&archive, false);
return CreateArchiveHandler(ai, false, (void **)&archive);
#endif
}
@@ -279,8 +385,9 @@ public:
return S_OK;
COM_TRY_END
}
#ifdef EXTERNAL_CODECS
return CreateArchiveHandler(ai, (void **)&archive, true);
return CreateArchiveHandler(ai, true, (void **)&archive);
#endif
}
@@ -291,7 +398,7 @@ public:
const CArcInfoEx &arc = Formats[i];
if (!arc.UpdateEnabled)
continue;
if (arc.Name.IsEqualToNoCase(name))
if (arc.Name.IsEqualTo_NoCase(name))
return i;
}
return -1;
@@ -300,4 +407,18 @@ public:
#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