diff options
Diffstat (limited to 'CPP/7zip/Archive/Common/CoderLoader.h')
-rwxr-xr-x | CPP/7zip/Archive/Common/CoderLoader.h | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/CPP/7zip/Archive/Common/CoderLoader.h b/CPP/7zip/Archive/Common/CoderLoader.h new file mode 100755 index 00000000..02322d8c --- /dev/null +++ b/CPP/7zip/Archive/Common/CoderLoader.h @@ -0,0 +1,147 @@ +// CoderLoader.h + +#ifndef __CODERLOADER_H +#define __CODERLOADER_H + +#include "../../../Common/String.h" +#include "../../../Common/MyCom.h" +#include "../../../Windows/DLL.h" +#include "../../ICoder.h" + +typedef UInt32 (WINAPI * CreateObjectPointer)( + const GUID *clsID, + const GUID *interfaceID, + void **outObject); + +class CCoderLibrary: public NWindows::NDLL::CLibrary +{ +public: + HRESULT CreateObject(REFGUID clsID, REFGUID iid, void **obj) + { + CreateObjectPointer createObject = (CreateObjectPointer) + GetProcAddress("CreateObject"); + if (createObject == NULL) + return GetLastError(); + return createObject(&clsID, &iid, obj); + } + + HRESULT CreateFilter(REFGUID clsID, ICompressFilter **filter) + { + return CreateObject(clsID, IID_ICompressFilter, (void **)filter); + } + + HRESULT CreateCoder(REFGUID clsID, ICompressCoder **coder) + { + return CreateObject(clsID, IID_ICompressCoder, (void **)coder); + } + + HRESULT CreateCoderSpec(REFGUID clsID, ICompressCoder **coder); + + HRESULT LoadAndCreateFilter(LPCTSTR filePath, REFGUID clsID, ICompressFilter **filter) + { + CCoderLibrary libTemp; + if (!libTemp.Load(filePath)) + return GetLastError(); + RINOK(libTemp.CreateFilter(clsID, filter)); + Attach(libTemp.Detach()); + return S_OK; + } + + + HRESULT LoadAndCreateCoder(LPCTSTR filePath, REFGUID clsID, ICompressCoder **coder) + { + CCoderLibrary libTemp; + if (!libTemp.Load(filePath)) + return GetLastError(); + RINOK(libTemp.CreateCoder(clsID, coder)); + Attach(libTemp.Detach()); + return S_OK; + } + + HRESULT LoadAndCreateCoderSpec(LPCTSTR filePath, REFGUID clsID, ICompressCoder **coder); + HRESULT CreateCoder2(REFGUID clsID, ICompressCoder2 **coder) + { + CreateObjectPointer createObject = (CreateObjectPointer) + GetProcAddress("CreateObject"); + if (createObject == NULL) + return GetLastError(); + return createObject(&clsID, &IID_ICompressCoder2, (void **)coder); + } + HRESULT LoadAndCreateCoder2(LPCTSTR filePath, REFGUID clsID, ICompressCoder2 **coder) + { + CCoderLibrary libTemp; + if (!libTemp.Load(filePath)) + return GetLastError(); + RINOK(libTemp.CreateCoder2(clsID, coder)); + Attach(libTemp.Detach()); + return S_OK; + } +}; + + +class CCoderLibraries +{ + struct CPathToLibraryPair + { + CSysString Path; + CCoderLibrary Libary; + }; + CObjectVector<CPathToLibraryPair> Pairs; +public: + int FindPath(LPCTSTR filePath) + { + for (int i = 0; i < Pairs.Size(); i++) + if (Pairs[i].Path.CompareNoCase(filePath) == 0) + return i; + return -1; + } + + HRESULT CreateCoder(LPCTSTR filePath, REFGUID clsID, ICompressCoder **coder) + { + int index = FindPath(filePath); + if (index < 0) + { + CPathToLibraryPair pair; + RINOK(pair.Libary.LoadAndCreateCoder(filePath, clsID, coder)); + pair.Path = filePath; + Pairs.Add(pair); + pair.Libary.Detach(); + return S_OK; + } + return Pairs[index].Libary.CreateCoder(clsID, coder); + } + + HRESULT CreateCoderSpec(LPCTSTR filePath, REFGUID clsID, ICompressCoder **coder) + { + int index = FindPath(filePath); + if (index < 0) + { + CPathToLibraryPair pair; + RINOK(pair.Libary.LoadAndCreateCoderSpec(filePath, clsID, coder)); + pair.Path = filePath; + Pairs.Add(pair); + pair.Libary.Detach(); + return S_OK; + } + return Pairs[index].Libary.CreateCoderSpec(clsID, coder); + } + + HRESULT CreateCoder2(LPCTSTR filePath, REFGUID clsID, ICompressCoder2 **coder) + { + int index = FindPath(filePath); + if (index < 0) + { + CPathToLibraryPair pair; + RINOK(pair.Libary.LoadAndCreateCoder2(filePath, clsID, coder)); + pair.Path = filePath; + Pairs.Add(pair); + pair.Libary.Detach(); + return S_OK; + } + return Pairs[index].Libary.CreateCoder2(clsID, coder); + } +}; + + +#endif + |