Files
easy7zip/7zip/Archive/7z/7zMethods.cpp
Igor Pavlov 8c1b5c7b7e 3.13
2016-05-28 00:15:41 +01:00

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;
}
}}