mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-06 21:14:58 -06:00
175 lines
4.5 KiB
C++
Executable File
175 lines
4.5 KiB
C++
Executable File
// 7zMethods.cpp
|
|
|
|
#include "StdAfx.h"
|
|
|
|
#include "7zMethods.h"
|
|
|
|
#include "../../../Windows/FileFind.h"
|
|
#include "../../../Windows/DLL.h"
|
|
#include "../../../Windows/PropVariant.h"
|
|
#include "../../../Windows/Synchronization.h"
|
|
|
|
#include "../../ICoder.h"
|
|
#include "../Common/CodecsPath.h"
|
|
|
|
using namespace NWindows;
|
|
|
|
namespace NArchive {
|
|
namespace N7z {
|
|
|
|
static CObjectVector<CMethodInfo2> g_Methods;
|
|
static bool g_Loaded = false;
|
|
|
|
typedef UINT32 (WINAPI *GetNumberOfMethodsFunc)(UINT32 *numMethods);
|
|
|
|
typedef UINT32 (WINAPI *GetMethodPropertyFunc)(
|
|
UINT32 index, PROPID propID, PROPVARIANT *value);
|
|
|
|
static void Load(const CSysString &folderPrefix)
|
|
{
|
|
NFile::NFind::CEnumerator enumerator(folderPrefix + CSysString(TEXT("*")));
|
|
NFile::NFind::CFileInfo fileInfo;
|
|
while (enumerator.Next(fileInfo))
|
|
{
|
|
if (fileInfo.IsDirectory())
|
|
continue;
|
|
CSysString filePath = folderPrefix + fileInfo.Name;
|
|
{
|
|
NDLL::CLibrary library;
|
|
if (!library.LoadEx(filePath, LOAD_LIBRARY_AS_DATAFILE))
|
|
continue;
|
|
}
|
|
NDLL::CLibrary library;
|
|
if (!library.Load(filePath))
|
|
continue;
|
|
GetMethodPropertyFunc getMethodProperty = (GetMethodPropertyFunc)
|
|
library.GetProcAddress("GetMethodProperty");
|
|
if (getMethodProperty == NULL)
|
|
continue;
|
|
|
|
UINT32 numMethods = 1;
|
|
GetNumberOfMethodsFunc getNumberOfMethodsFunc = (GetNumberOfMethodsFunc)
|
|
library.GetProcAddress("GetNumberOfMethods");
|
|
if (getNumberOfMethodsFunc != NULL)
|
|
if (getNumberOfMethodsFunc(&numMethods) != S_OK)
|
|
continue;
|
|
|
|
for(UINT32 i = 0; i < numMethods; i++)
|
|
{
|
|
CMethodInfo2 info;
|
|
info.FilePath = filePath;
|
|
|
|
NWindows::NCOM::CPropVariant propVariant;
|
|
if (getMethodProperty(i, NMethodPropID::kID, &propVariant) != S_OK)
|
|
continue;
|
|
if (propVariant.vt != VT_BSTR)
|
|
continue;
|
|
info.MethodID.IDSize = SysStringByteLen(propVariant.bstrVal);
|
|
memmove(info.MethodID.ID, propVariant.bstrVal, info.MethodID.IDSize);
|
|
propVariant.Clear();
|
|
|
|
if (getMethodProperty(i, NMethodPropID::kName, &propVariant) != S_OK)
|
|
continue;
|
|
if (propVariant.vt == VT_EMPTY)
|
|
{
|
|
}
|
|
else if (propVariant.vt == VT_BSTR)
|
|
info.Name = propVariant.bstrVal;
|
|
else
|
|
continue;
|
|
propVariant.Clear();
|
|
|
|
if (getMethodProperty (i, NMethodPropID::kEncoder, &propVariant) != S_OK)
|
|
continue;
|
|
if (propVariant.vt == VT_EMPTY)
|
|
info.EncoderIsAssigned = false;
|
|
else if (propVariant.vt == VT_BSTR)
|
|
{
|
|
info.EncoderIsAssigned = true;
|
|
info.Encoder = *(const GUID *)propVariant.bstrVal;
|
|
}
|
|
else
|
|
continue;
|
|
propVariant.Clear();
|
|
|
|
if (getMethodProperty (i, NMethodPropID::kDecoder, &propVariant) != S_OK)
|
|
continue;
|
|
if (propVariant.vt == VT_EMPTY)
|
|
info.DecoderIsAssigned = false;
|
|
else if (propVariant.vt == VT_BSTR)
|
|
{
|
|
info.DecoderIsAssigned = true;
|
|
info.Decoder = *(const GUID *)propVariant.bstrVal;
|
|
}
|
|
else
|
|
continue;
|
|
propVariant.Clear();
|
|
|
|
if (getMethodProperty (i, NMethodPropID::kInStreams, &propVariant) != S_OK)
|
|
continue;
|
|
if (propVariant.vt == VT_EMPTY)
|
|
info.NumInStreams = 1;
|
|
else if (propVariant.vt == VT_UI4)
|
|
info.NumInStreams = propVariant.ulVal;
|
|
else
|
|
continue;
|
|
propVariant.Clear();
|
|
|
|
if (getMethodProperty (i, NMethodPropID::kOutStreams, &propVariant) != S_OK)
|
|
continue;
|
|
if (propVariant.vt == VT_EMPTY)
|
|
info.NumOutStreams = 1;
|
|
else if (propVariant.vt == VT_UI4)
|
|
info.NumOutStreams = propVariant.ulVal;
|
|
else
|
|
continue;
|
|
propVariant.Clear();
|
|
|
|
g_Methods.Add(info);
|
|
}
|
|
}
|
|
}
|
|
|
|
static NSynchronization::CCriticalSection g_CriticalSection;
|
|
|
|
void LoadMethodMap()
|
|
{
|
|
NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
|
|
if (g_Loaded)
|
|
return;
|
|
g_Loaded = true;
|
|
Load(GetCodecsFolderPrefix());
|
|
}
|
|
|
|
bool GetMethodInfo(const CMethodID &methodID, CMethodInfo &methodInfo)
|
|
{
|
|
for(int i = 0; i < g_Methods.Size(); i++)
|
|
{
|
|
const CMethodInfo2 &method = g_Methods[i];
|
|
if (method.MethodID == methodID)
|
|
{
|
|
methodInfo = (CMethodInfo)method;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool GetMethodInfo(const UString &name, CMethodInfo2 &methodInfo)
|
|
{
|
|
for(int i = 0; i < g_Methods.Size(); i++)
|
|
{
|
|
const CMethodInfo2 &method = g_Methods[i];
|
|
if (method.Name.CollateNoCase(name) == 0)
|
|
{
|
|
methodInfo = method;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
}}
|
|
|
|
|