// 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 |