// LoadCodecs.h
#ifndef __LOAD_CODECS_H
#define __LOAD_CODECS_H
#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
struct CDllCodecInfo
{
CLSID Encoder;
CLSID Decoder;
bool EncoderIsAssigned;
bool DecoderIsAssigned;
int LibIndex;
UInt32 CodecIndex;
};
struct CDllHasherInfo
{
int LibIndex;
UInt32 HasherIndex;
};
#include "../../Archive/IArchive.h"
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 EXTERNAL_CODECS
#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
struct CCodecLib
#ifdef NEW_FOLDER_INTERFACE
: public CCodecIcons
#endif
{
NWindows::NDLL::CLibrary Lib;
FString Path;
Func_GetMethodProperty GetMethodProperty;
Func_CreateObject CreateObject;
CMyComPtr<IHashers> Hashers;
#ifdef NEW_FOLDER_INTERFACE
void LoadIcons() { CCodecIcons::LoadIcons((HMODULE)Lib); }
#endif
CCodecLib(): GetMethodProperty(NULL) {}
};
#endif
class CCodecs:
#ifdef EXTERNAL_CODECS
public ICompressCodecsInfo,
public IHashers,
#else
public IUnknown,
#endif
public CMyUnknownImp
{
public:
#ifdef EXTERNAL_CODECS
CObjectVector<CCodecLib> Libs;
CRecordVector<CDllCodecInfo> Codecs;
CRecordVector<CDllHasherInfo> Hashers;
#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);
}
#endif
public:
CObjectVector<CArcInfoEx> Formats;
bool CaseSensitiveChange;
bool CaseSensitive;
CCodecs(): CaseSensitiveChange(false), CaseSensitive(false) {}
const wchar_t *GetFormatNamePtr(int formatIndex)
{
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(GetNumberOfMethods)(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_(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 GetCodecLibIndex(UInt32 index);
bool GetCodecEncoderIsAssigned(UInt32 index);
HRESULT GetCodecId(UInt32 index, UInt64 &id);
UString GetCodecName(UInt32 index);
int GetHasherLibIndex(UInt32 index);
UInt64 GetHasherId(UInt32 index);
UString 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, (void **)&archive, false);
#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, (void **)&archive, true);
#endif
}
int FindOutFormatFromName(const UString &name) const
{
FOR_VECTOR (i, Formats)
{
const CArcInfoEx &arc = Formats[i];
if (!arc.UpdateEnabled)
continue;
if (arc.Name.IsEqualToNoCase(name))
return i;
}
return -1;
}
#endif // _SFX
};
#endif