mirror of
https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git
synced 2026-04-19 13:46:16 +10:00
The module of package reading is tested.
This commit is contained in:
@@ -7,10 +7,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "appinstaller", "AppInstalle
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pkgread", "pkgread\pkgread.vcxproj", "{A7753282-AA16-43D9-8ACA-7065239DD702}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pkgread", "pkgread\pkgread.vcxproj", "{A7753282-AA16-43D9-8ACA-7065239DD702}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "prireader", "prireader\prireader.vcxproj", "{D8CFAA98-0A77-4C5B-A61B-11EF44206712}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dlltest", "dlltest\dlltest.vcxproj", "{F5CCB3AB-AC43-432A-862D-4F264760B09B}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dlltest", "dlltest\dlltest.vcxproj", "{F5CCB3AB-AC43-432A-862D-4F264760B09B}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "priread", "priread\priread.vcxproj", "{99D714D9-F40D-425B-BAFA-8B41C17971A5}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|x64 = Debug|x64
|
Debug|x64 = Debug|x64
|
||||||
@@ -35,14 +35,6 @@ Global
|
|||||||
{A7753282-AA16-43D9-8ACA-7065239DD702}.Release|x64.Build.0 = Release|x64
|
{A7753282-AA16-43D9-8ACA-7065239DD702}.Release|x64.Build.0 = Release|x64
|
||||||
{A7753282-AA16-43D9-8ACA-7065239DD702}.Release|x86.ActiveCfg = Release|Win32
|
{A7753282-AA16-43D9-8ACA-7065239DD702}.Release|x86.ActiveCfg = Release|Win32
|
||||||
{A7753282-AA16-43D9-8ACA-7065239DD702}.Release|x86.Build.0 = Release|Win32
|
{A7753282-AA16-43D9-8ACA-7065239DD702}.Release|x86.Build.0 = Release|Win32
|
||||||
{D8CFAA98-0A77-4C5B-A61B-11EF44206712}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{D8CFAA98-0A77-4C5B-A61B-11EF44206712}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{D8CFAA98-0A77-4C5B-A61B-11EF44206712}.Debug|x86.ActiveCfg = Debug|Win32
|
|
||||||
{D8CFAA98-0A77-4C5B-A61B-11EF44206712}.Debug|x86.Build.0 = Debug|Win32
|
|
||||||
{D8CFAA98-0A77-4C5B-A61B-11EF44206712}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{D8CFAA98-0A77-4C5B-A61B-11EF44206712}.Release|x64.Build.0 = Release|x64
|
|
||||||
{D8CFAA98-0A77-4C5B-A61B-11EF44206712}.Release|x86.ActiveCfg = Release|Win32
|
|
||||||
{D8CFAA98-0A77-4C5B-A61B-11EF44206712}.Release|x86.Build.0 = Release|Win32
|
|
||||||
{F5CCB3AB-AC43-432A-862D-4F264760B09B}.Debug|x64.ActiveCfg = Debug|x64
|
{F5CCB3AB-AC43-432A-862D-4F264760B09B}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{F5CCB3AB-AC43-432A-862D-4F264760B09B}.Debug|x64.Build.0 = Debug|x64
|
{F5CCB3AB-AC43-432A-862D-4F264760B09B}.Debug|x64.Build.0 = Debug|x64
|
||||||
{F5CCB3AB-AC43-432A-862D-4F264760B09B}.Debug|x86.ActiveCfg = Debug|Win32
|
{F5CCB3AB-AC43-432A-862D-4F264760B09B}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
@@ -51,6 +43,14 @@ Global
|
|||||||
{F5CCB3AB-AC43-432A-862D-4F264760B09B}.Release|x64.Build.0 = Release|x64
|
{F5CCB3AB-AC43-432A-862D-4F264760B09B}.Release|x64.Build.0 = Release|x64
|
||||||
{F5CCB3AB-AC43-432A-862D-4F264760B09B}.Release|x86.ActiveCfg = Release|Win32
|
{F5CCB3AB-AC43-432A-862D-4F264760B09B}.Release|x86.ActiveCfg = Release|Win32
|
||||||
{F5CCB3AB-AC43-432A-862D-4F264760B09B}.Release|x86.Build.0 = Release|Win32
|
{F5CCB3AB-AC43-432A-862D-4F264760B09B}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{99D714D9-F40D-425B-BAFA-8B41C17971A5}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{99D714D9-F40D-425B-BAFA-8B41C17971A5}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{99D714D9-F40D-425B-BAFA-8B41C17971A5}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{99D714D9-F40D-425B-BAFA-8B41C17971A5}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{99D714D9-F40D-425B-BAFA-8B41C17971A5}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{99D714D9-F40D-425B-BAFA-8B41C17971A5}.Release|x64.Build.0 = Release|x64
|
||||||
|
{99D714D9-F40D-425B-BAFA-8B41C17971A5}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{99D714D9-F40D-425B-BAFA-8B41C17971A5}.Release|x86.Build.0 = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
301
dlltest/main.cpp
301
dlltest/main.cpp
@@ -2,75 +2,252 @@
|
|||||||
#include "..\pkgread\pkgread.h"
|
#include "..\pkgread\pkgread.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
void read_package (const std::wstring &filepath)
|
||||||
|
{
|
||||||
|
package_reader pr (filepath);
|
||||||
|
std::wcout << L"Is Valid: " << (pr.valid () ? L"true" : L"false") << std::endl;
|
||||||
|
std::wcout << L"Package Type: ";
|
||||||
|
switch (pr.package_type ())
|
||||||
|
{
|
||||||
|
case PKGTYPE_APPX: std::wcout << L"Appx"; break;
|
||||||
|
case PKGTYPE_BUNDLE: std::wcout << L"AppxBundle"; break;
|
||||||
|
}
|
||||||
|
std::wcout << std::endl;
|
||||||
|
std::wcout << L"Package Role: ";
|
||||||
|
switch (pr.package_role ())
|
||||||
|
{
|
||||||
|
case PKGROLE_APPLICATION: std::wcout << L"Application"; break;
|
||||||
|
case PKGROLE_FRAMEWORK: std::wcout << L"Framework"; break;
|
||||||
|
case PKGROLE_RESOURCE: std::wcout << L"Resource"; break;
|
||||||
|
case PKGROLE_UNKNOWN: std::wcout << L"Unknown"; break;
|
||||||
|
}
|
||||||
|
std::wcout << std::endl;
|
||||||
|
auto id = pr.get_identity ();
|
||||||
|
std::wcout << L"Identity" << std::endl;
|
||||||
|
std::wcout << L"\tName: " << id.name () << std::endl;
|
||||||
|
std::wcout << L"\tPublisher: " << id.publisher () << std::endl;
|
||||||
|
auto ver = id.version ();
|
||||||
|
std::wcout << L"\tVersion: " << ver.major << L"." << ver.minor << L"." << ver.build << L"." << ver.revision << std::endl;
|
||||||
|
std::wcout << L"\tPackage Family Name: " << id.package_family_name () << std::endl;
|
||||||
|
std::wcout << L"\tPackage Full Name: " << id.package_full_name () << std::endl;
|
||||||
|
std::wcout << L"\tResource Id: " << id.resource_id () << std::endl;
|
||||||
|
std::wcout << L"\tArchitecture: ";
|
||||||
|
DWORD archi = id.architecture ();
|
||||||
|
for (size_t i = 0xF; i > 0; i /= 2)
|
||||||
|
{
|
||||||
|
if (archi & i)
|
||||||
|
{
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case PKG_ARCHITECTURE_ARM: std::wcout << "Arm"; break;
|
||||||
|
case PKG_ARCHITECTURE_ARM64: std::wcout << "Arm64"; break;
|
||||||
|
case PKG_ARCHITECTURE_NEUTRAL: std::wcout << "Neutral"; break;
|
||||||
|
case PKG_ARCHITECTURE_X64: std::wcout << "x64"; break;
|
||||||
|
case PKG_ARCHITECTURE_X86: std::wcout << "x86"; break;
|
||||||
|
default: continue;
|
||||||
|
}
|
||||||
|
std::wcout << L", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::wcout << std::endl;
|
||||||
|
ver = id.version (true);
|
||||||
|
std::wcout << L"\tVersion (Appx): " << ver.major << L"." << ver.minor << L"." << ver.build << L"." << ver.revision << std::endl;
|
||||||
|
std::wcout << L"Properties" << std::endl;
|
||||||
|
auto prop = pr.get_properties ();
|
||||||
|
std::wcout << L"\tDisplay Name: " << prop.display_name () << std::endl;
|
||||||
|
std::wcout << L"\tDescription: " << prop.description () << std::endl;
|
||||||
|
std::wcout << L"\tPublisher Display Name: " << prop.publisher_display_name () << std::endl;
|
||||||
|
std::wcout << L"\tLogo: " << prop.logo () << std::endl;
|
||||||
|
std::wcout << L"\tFramework: " << (prop.framework () ? L"true" : L"false") << std::endl;
|
||||||
|
std::wcout << L"\tResource Package: " << (prop.resource_package () ? L"true" : L"false") << std::endl;
|
||||||
|
auto preq = pr.get_prerequisites ();
|
||||||
|
std::wcout << L"Prerequisites" << std::endl;
|
||||||
|
ver = preq.os_min_version ();
|
||||||
|
std::wcout << L"\tOS Min Version: " << ver.major << L"." << ver.minor << L"." << ver.build << L"." << ver.revision << std::endl;
|
||||||
|
ver = preq.os_max_version_tested ();
|
||||||
|
std::wcout << L"\tOS Max Version Tested: " << ver.major << L"." << ver.minor << L"." << ver.build << L"." << ver.revision << std::endl;
|
||||||
|
std::wcout << L"Resources" << std::endl;
|
||||||
|
auto res = pr.get_resources ();
|
||||||
|
{
|
||||||
|
std::vector <std::wstring> langs;
|
||||||
|
std::vector <UINT32> scales;
|
||||||
|
std::vector <DWORD> dx_levels;
|
||||||
|
res.languages (langs);
|
||||||
|
res.scales (scales);
|
||||||
|
res.dx_feature_level (dx_levels);
|
||||||
|
std::wcout << L"\tSupported Languages: ";
|
||||||
|
for (auto &it : langs)
|
||||||
|
{
|
||||||
|
std::wcout << it << L", ";
|
||||||
|
}
|
||||||
|
std::wcout << std::endl;
|
||||||
|
std::wcout << L"\tSupported Scales: ";
|
||||||
|
for (auto &it : scales)
|
||||||
|
{
|
||||||
|
std::wcout << it << L", ";
|
||||||
|
}
|
||||||
|
std::wcout << std::endl;
|
||||||
|
std::wcout << L"\tSupported Languages: ";
|
||||||
|
for (auto &it : dx_levels)
|
||||||
|
{
|
||||||
|
switch (it)
|
||||||
|
{
|
||||||
|
case PKG_RESOURCES_DXFEATURE_LEVEL9: std::wcout << L"9, "; break;
|
||||||
|
case PKG_RESOURCES_DXFEATURE_LEVEL10: std::wcout << L"10, "; break;
|
||||||
|
case PKG_RESOURCES_DXFEATURE_LEVEL11: std::wcout << L"11, "; break;
|
||||||
|
case PKG_RESOURCES_DXFEATURE_LEVEL12: std::wcout << L"12, "; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::wcout << std::endl;
|
||||||
|
}
|
||||||
|
std::wcout << L"Capabilities" << std::endl;
|
||||||
|
auto cap = pr.get_capabilities ();
|
||||||
|
{
|
||||||
|
std::vector <std::wstring> caps;
|
||||||
|
std::vector <std::wstring> devicecaps;
|
||||||
|
cap.capabilities_name (caps);
|
||||||
|
cap.device_capabilities (devicecaps);
|
||||||
|
std::wcout << L"\tCapabilities: ";
|
||||||
|
for (auto &it : caps)
|
||||||
|
{
|
||||||
|
std::wcout << it << L", ";
|
||||||
|
}
|
||||||
|
std::wcout << std::endl;
|
||||||
|
std::wcout << L"\tDevice Capabilities: ";
|
||||||
|
for (auto &it : devicecaps)
|
||||||
|
{
|
||||||
|
std::wcout << it << L", ";
|
||||||
|
}
|
||||||
|
std::wcout << std::endl;
|
||||||
|
}
|
||||||
|
std::wcout << L"Applications" << std::endl;
|
||||||
|
auto apps = pr.get_applications ();
|
||||||
|
{
|
||||||
|
std::vector <package_reader::application> appmaps;
|
||||||
|
apps.get (appmaps);
|
||||||
|
size_t cnt = 1;
|
||||||
|
for (auto &it : appmaps)
|
||||||
|
{
|
||||||
|
std::wcout << L"\tApplication" << cnt ++ << std::endl;
|
||||||
|
for (auto &it_s : it)
|
||||||
|
{
|
||||||
|
std::wcout << L"\t\t" << it_s.first << L": " << it_s.second << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto deps = pr.get_dependencies ();
|
||||||
|
std::wcout << L"Dependencies" << std::endl;
|
||||||
|
{
|
||||||
|
std::vector <package_reader::dependency> deparr;
|
||||||
|
deps.get (deparr);
|
||||||
|
size_t cnt = 1;
|
||||||
|
for (auto &it : deparr)
|
||||||
|
{
|
||||||
|
std::wcout << L"\tDependency" << cnt ++ << std::endl;
|
||||||
|
std::wcout << L"\t\tName: " << it.name << std::endl;
|
||||||
|
std::wcout << L"\t\tPublisher: " << it.publisher << std::endl;
|
||||||
|
ver = it.vermin;
|
||||||
|
std::wcout << L"\t\tMin Version: " << ver.major << L"." << ver.minor << L"." << ver.build << L"." << ver.revision << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct head
|
||||||
|
{
|
||||||
|
CHAR szMagic [8];
|
||||||
|
WORD wPlaceholder1, // 0
|
||||||
|
wPlaceholder2; // 1
|
||||||
|
DWORD dwFileSize,
|
||||||
|
dwToCOffset,
|
||||||
|
dwSectStartOffset;
|
||||||
|
WORD wSectCount,
|
||||||
|
wPlaceholder3; // 0xFFFF
|
||||||
|
DWORD dwPlaceholder4; // 0
|
||||||
|
};
|
||||||
|
struct footer
|
||||||
|
{
|
||||||
|
DWORD dwChkCode, // 0xDEFFFADE
|
||||||
|
dwTotalFileSize;
|
||||||
|
};
|
||||||
|
struct tocentry
|
||||||
|
{
|
||||||
|
CHAR szIdentifier [16] = {0};
|
||||||
|
WORD wFlags = 0;
|
||||||
|
WORD wSectFlags = 0;
|
||||||
|
DWORD dwSectQualifier = 0;
|
||||||
|
DWORD dwSectOffset = 0;
|
||||||
|
DWORD dwSectLength = 0;
|
||||||
|
};
|
||||||
|
// #pragma pack (push, 1)
|
||||||
|
struct section_header
|
||||||
|
{
|
||||||
|
CHAR szIdentifier [16] = {0};
|
||||||
|
DWORD dwQualifier = 0;
|
||||||
|
WORD wFlags = 0;
|
||||||
|
DWORD dwLength = 0;
|
||||||
|
DWORD dwPlaceholder1 = -1; // 0
|
||||||
|
};
|
||||||
|
struct section_check
|
||||||
|
{
|
||||||
|
DWORD dwChkCode = 0, // 0xDEF5FADE
|
||||||
|
dwSectLength = 0;
|
||||||
|
};
|
||||||
|
|
||||||
int main (int argc, char *argv [])
|
int main (int argc, char *argv [])
|
||||||
{
|
{
|
||||||
// 1. 创建 Reader 对象
|
setlocale (LC_ALL, "");
|
||||||
HPKGREAD hReader = CreatePackageReader ();
|
std::wcout.imbue (std::locale ("", LC_CTYPE));
|
||||||
if (!hReader) {
|
|
||||||
std::wcerr << L"CreatePackageReader failed!" << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
std::wcout << L"CreatePackageReader succeeded!" << std::endl;
|
|
||||||
|
|
||||||
// 2. 加载包文件
|
|
||||||
std::wcout << L"Please enter the file path: " << std::endl;
|
std::wcout << L"Please enter the file path: " << std::endl;
|
||||||
std::wcout << L"\\> ";
|
std::wcout << L"\\> ";
|
||||||
std::wstring pkgPathStr;
|
std::wstring pkgPathStr = L"E:\\Profiles\\Bruce\\Desktop\\resources.pri";
|
||||||
std::getline (std::wcin, pkgPathStr);
|
//std::getline (std::wcin, pkgPathStr);
|
||||||
if (!pkgPathStr.empty () && pkgPathStr.front () == L'\"' && pkgPathStr.back () == L'\"' && pkgPathStr.size () >= 2) {
|
pkgPathStr.erase (
|
||||||
pkgPathStr = pkgPathStr.substr (1, pkgPathStr.size () - 2);
|
std::remove (pkgPathStr.begin (), pkgPathStr.end (), L'\"'),
|
||||||
|
pkgPathStr.end ()
|
||||||
|
);
|
||||||
|
HANDLE hFile = CreateFileW (
|
||||||
|
pkgPathStr.c_str (), // 文件名
|
||||||
|
GENERIC_READ, // 只读
|
||||||
|
FILE_SHARE_READ, // 允许其他进程读取
|
||||||
|
NULL, // 默认安全属性
|
||||||
|
OPEN_EXISTING, // 必须文件存在
|
||||||
|
FILE_ATTRIBUTE_NORMAL, // 普通文件
|
||||||
|
NULL // 无模板
|
||||||
|
);
|
||||||
|
head header;
|
||||||
|
footer foot;
|
||||||
|
DWORD headRead = 0, footRead = 0;
|
||||||
|
ReadFile (hFile, &header, sizeof (header), &headRead, NULL);
|
||||||
|
SetFilePointer (hFile, header.dwFileSize - 16, NULL, FILE_BEGIN);
|
||||||
|
ReadFile (hFile, &foot, sizeof (foot), &footRead, NULL);
|
||||||
|
SetFilePointer (hFile, header.dwToCOffset, NULL, FILE_BEGIN);
|
||||||
|
std::vector <tocentry> tocs;
|
||||||
|
for (size_t i = 0; i < header.wSectCount; i ++)
|
||||||
|
{
|
||||||
|
tocentry toc;
|
||||||
|
DWORD dwRead;
|
||||||
|
ReadFile (hFile, &toc, sizeof (toc), &dwRead, NULL);
|
||||||
|
tocs.push_back (toc);
|
||||||
}
|
}
|
||||||
LPCWSTR pkgPath = pkgPathStr.c_str ();
|
for (size_t i = 0; i < header.wSectCount; i ++)
|
||||||
if (!LoadPackageFromFile (hReader, pkgPath)) {
|
{
|
||||||
std::wcerr << L"LoadPackageFromFile failed for " << pkgPath << std::endl;
|
SetFilePointer (hFile, header.dwSectStartOffset + tocs [i].dwSectOffset, NULL, FILE_BEGIN);
|
||||||
DestroyPackageReader (hReader);
|
section_header sh;
|
||||||
return 1;
|
section_check sc;
|
||||||
|
DWORD dwsh, dwsc;
|
||||||
|
ReadFile (hFile, &sh, sizeof (sh), &dwsh, NULL);
|
||||||
|
SetFilePointer (hFile, sh.dwLength - 16 - 24, NULL, FILE_CURRENT);
|
||||||
|
ReadFile (hFile, &sc, sizeof (sc), &dwsc, NULL);
|
||||||
|
SetFilePointer (hFile, 32 - sh.dwLength, NULL, FILE_CURRENT);
|
||||||
|
//subsection ss;
|
||||||
|
//ss.dwOffset = SetFilePointer (hFile, 0, NULL, FILE_CURRENT);
|
||||||
|
//ss.dwLength = sh.dwLength - 16 - 24;
|
||||||
|
//SetFilePointer (hFile, 32, NULL, FILE_CURRENT);
|
||||||
}
|
}
|
||||||
std::wcout << L"LoadPackageFromFile succeeded!" << std::endl;
|
CloseHandle (hFile);
|
||||||
|
|
||||||
// 3. 验证包类型
|
|
||||||
WORD type = GetPackageType (hReader);
|
|
||||||
std::wcout << L"Package Type: " << type << std::endl;
|
|
||||||
|
|
||||||
// 4. 验证包有效性
|
|
||||||
BOOL valid = IsPackageValid (hReader);
|
|
||||||
std::wcout << L"IsPackageValid: " << (valid ? L"True" : L"False") << std::endl;
|
|
||||||
|
|
||||||
// 5. 获取包名称
|
|
||||||
LPWSTR pkgName = GetPackageIdentityStringValue (hReader, PKG_IDENTITY_NAME);
|
|
||||||
if (pkgName)
|
|
||||||
std::wcout << L"Package Name: " << pkgName << std::endl;
|
|
||||||
else
|
|
||||||
std::wcerr << L"GetPackageIdentityStringValue PKG_IDENTITY_NAME failed!" << std::endl;
|
|
||||||
|
|
||||||
// 6. 获取包版本
|
|
||||||
VERSION ver;
|
|
||||||
if (GetPackageIdentityVersion (hReader, &ver, FALSE)) {
|
|
||||||
std::wcout << L"Package Version: " << ver.major << L"." << ver.minor << L"." << ver.build << L"." << ver.revision << std::endl;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
std::wcerr << L"GetPackageIdentityVersion failed!" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 7. 列举所有 Application 名称
|
|
||||||
HLIST_PVOID appList = GetAllApplicationItemsName ();
|
|
||||||
if (appList) {
|
|
||||||
std::wcout << L"Application Count: " << appList->dwSize << std::endl;
|
|
||||||
for (DWORD i = 0; i < appList->dwSize; ++i) {
|
|
||||||
LPCWSTR appName = (LPCWSTR)appList->alpVoid [i];
|
|
||||||
if (appName)
|
|
||||||
std::wcout << L"App[" << i << L"]: " << appName << std::endl;
|
|
||||||
}
|
|
||||||
DestroyApplicationItemsName (appList);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
std::wcerr << L"GetAllApplicationItemsName failed!" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 8. 清理
|
|
||||||
DestroyPackageReader (hReader);
|
|
||||||
|
|
||||||
system ("pause");
|
system ("pause");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -766,7 +766,7 @@ HLIST_PVOID GetCapabilitiesList (_In_ HPKGREAD hReader)
|
|||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
size_t len = sizeof (LIST_PVOID) * sizeof (LPWSTR) * caps.size ();
|
size_t len = sizeof (LIST_PVOID) + sizeof (LPWSTR) * caps.size ();
|
||||||
HLIST_PVOID hList = (HLIST_PVOID)malloc (len);
|
HLIST_PVOID hList = (HLIST_PVOID)malloc (len);
|
||||||
ZeroMemory (hList, len);
|
ZeroMemory (hList, len);
|
||||||
hList->dwSize = 0;
|
hList->dwSize = 0;
|
||||||
@@ -811,7 +811,7 @@ HLIST_PVOID GetDeviceCapabilitiesList (_In_ HPKGREAD hReader)
|
|||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
size_t len = sizeof (LIST_PVOID) * sizeof (LPWSTR) * caps.size ();
|
size_t len = sizeof (LIST_PVOID) + sizeof (LPWSTR) * caps.size ();
|
||||||
HLIST_PVOID hList = (HLIST_PVOID)malloc (len);
|
HLIST_PVOID hList = (HLIST_PVOID)malloc (len);
|
||||||
ZeroMemory (hList, len);
|
ZeroMemory (hList, len);
|
||||||
hList->dwSize = 0;
|
hList->dwSize = 0;
|
||||||
@@ -831,3 +831,32 @@ void DestroyWStringList (_In_ HLIST_PVOID hList)
|
|||||||
}
|
}
|
||||||
free (hList);
|
free (hList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prerequisite
|
||||||
|
BOOL GetPackagePrerequisite (_In_ HPKGREAD hReader, _In_ LPCWSTR lpName, _Outptr_ VERSION *pVerRet)
|
||||||
|
{
|
||||||
|
auto ptr = ToPtrPackage (hReader);
|
||||||
|
if (!ptr) return FALSE;
|
||||||
|
switch (ptr->type ())
|
||||||
|
{
|
||||||
|
case PackageType::single: {
|
||||||
|
auto reader = ptr->appx_reader ();
|
||||||
|
auto pre = reader.prerequisites ();
|
||||||
|
auto ver = pre.get_version (lpName ? lpName : L"");
|
||||||
|
*pVerRet = VersionClassToStruct (ver);
|
||||||
|
return !ver.empty ();
|
||||||
|
} break;
|
||||||
|
case PackageType::bundle: {
|
||||||
|
auto br = ptr->bundle_reader ();
|
||||||
|
CComPtr <IAppxPackageReader> ar;
|
||||||
|
HRESULT hr = br.random_application_package (&ar);
|
||||||
|
if (FAILED (hr)) return false;
|
||||||
|
auto reader = appxreader (ar.p);
|
||||||
|
auto pre = reader.prerequisites ();
|
||||||
|
auto ver = pre.get_version (lpName ? lpName : L"");
|
||||||
|
*pVerRet = VersionClassToStruct (ver);
|
||||||
|
return !ver.empty ();
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
@@ -12,35 +12,48 @@
|
|||||||
#define PKGREAD_API __declspec(dllimport)
|
#define PKGREAD_API __declspec(dllimport)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#define _DEFAULT_INIT_VALUE_(_init_value_) = _init_value_
|
#define _DEFAULT_INIT_VALUE_(_init_value_) = _init_value_
|
||||||
#ifdef PKGREAD_EXPORTS
|
#ifdef PKGREAD_EXPORTS
|
||||||
#define _DEFAULT_INIT_VALUE_FORFUNC_(_init_value_) = _init_value_
|
#define _DEFAULT_INIT_VALUE_FORFUNC_(_init_value_) = _init_value_
|
||||||
#else
|
#else
|
||||||
#define _DEFAULT_INIT_VALUE_FORFUNC_(_init_value_)
|
#define _DEFAULT_INIT_VALUE_FORFUNC_(_init_value_)
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define _DEFAULT_INIT_VALUE_(_init_value_)
|
#define _DEFAULT_INIT_VALUE_(_init_value_)
|
||||||
#define _DEFAULT_INIT_VALUE_FORFUNC_(_init_value_)
|
#define _DEFAULT_INIT_VALUE_FORFUNC_(_init_value_)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined (__cplusplus) && defined (PKGREAD_EXPORTS)
|
||||||
|
#include <iostream>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef _TYPE_STRUCT_VERSION_
|
#ifndef _TYPE_STRUCT_VERSION_
|
||||||
#define _TYPE_STRUCT_VERSION_
|
#define _TYPE_STRUCT_VERSION_
|
||||||
typedef struct _VERSION
|
typedef struct _VERSION
|
||||||
|
{
|
||||||
|
UINT16 major _DEFAULT_INIT_VALUE_ (0),
|
||||||
|
minor _DEFAULT_INIT_VALUE_ (0),
|
||||||
|
build _DEFAULT_INIT_VALUE_ (0),
|
||||||
|
revision _DEFAULT_INIT_VALUE_ (0);
|
||||||
|
#if defined (__cplusplus) && defined (PKGREAD_EXPORTS)
|
||||||
|
_VERSION (UINT16 major = 0, UINT16 minor = 0, UINT16 build = 0, UINT16 revision = 0):
|
||||||
|
major (major), minor (minor), build (build), revision (revision) {}
|
||||||
|
friend std::ostream &operator << (std::ostream &o, const _VERSION &v)
|
||||||
{
|
{
|
||||||
#if defined (__cplusplus) && defined (PKGREAD_EXPORTS)
|
return o << v.major << "." << v.minor << "." << v.build << "." << v.revision;
|
||||||
_VERSION (UINT16 major = 0, UINT16 minor = 0, UINT16 build = 0, UINT16 revision = 0):
|
}
|
||||||
major (major), minor (minor), build (build), revision (revision) {}
|
friend std::wostream &operator << (std::wostream &o, const _VERSION &v)
|
||||||
#endif
|
{
|
||||||
UINT16 major _DEFAULT_INIT_VALUE_ (0),
|
return o << v.major << L"." << v.minor << L"." << v.build << L"." << v.revision;
|
||||||
minor _DEFAULT_INIT_VALUE_ (0),
|
}
|
||||||
build _DEFAULT_INIT_VALUE_ (0),
|
#endif
|
||||||
revision _DEFAULT_INIT_VALUE_ (0);
|
} VERSION;
|
||||||
} VERSION;
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _TYPE_STRUCT_LIST_PVOID_
|
#ifndef _TYPE_STRUCT_LIST_PVOID_
|
||||||
@@ -106,6 +119,11 @@ extern "C"
|
|||||||
// 获取身份信息能获取文本值的项。支持 PKG_IDENTITY_* 前缀的宏 NAME, PUBLISHER, PACKAGEFAMILYNAME, PACKAGEFULLNAME, RESOURCEID。
|
// 获取身份信息能获取文本值的项。支持 PKG_IDENTITY_* 前缀的宏 NAME, PUBLISHER, PACKAGEFAMILYNAME, PACKAGEFULLNAME, RESOURCEID。
|
||||||
// 当与 PKG_IDENTITY_BUNDLE_GETAPPXINFO 通过位或结合时,则获取 AppxBundle 中某一个应用包。
|
// 当与 PKG_IDENTITY_BUNDLE_GETAPPXINFO 通过位或结合时,则获取 AppxBundle 中某一个应用包。
|
||||||
PKGREAD_API LPWSTR GetPackageIdentityStringValue (_In_ HPKGREAD hReader, _In_ DWORD dwName);
|
PKGREAD_API LPWSTR GetPackageIdentityStringValue (_In_ HPKGREAD hReader, _In_ DWORD dwName);
|
||||||
|
#define GetPackageIdentityName(_In_hReader_) GetPackageIdentityStringValue (_In_hReader_, PKG_IDENTITY_NAME)
|
||||||
|
#define GetPackageIdentityPublisher(_In_hReader_) GetPackageIdentityStringValue (_In_hReader_, PKG_IDENTITY_PUBLISHER)
|
||||||
|
#define GetPackageIdentityPackageFamilyName(_In_hReader_) GetPackageIdentityStringValue (_In_hReader_, PKG_IDENTITY_PACKAGEFAMILYNAME)
|
||||||
|
#define GetPackageIdentityPackageFullName(_In_hReader_) GetPackageIdentityStringValue (_In_hReader_, PKG_IDENTITY_PACKAGEFULLNAME)
|
||||||
|
#define GetPackageIdentityResourceId(_In_hReader_) GetPackageIdentityStringValue (_In_hReader_, PKG_IDENTITY_RESOURCEID)
|
||||||
// 获取身份信息。当 bGetSubPkgVer 为真,且打开的包为 AppxBundle 包,返回 AppxBundle 包中的某个应用包的版本号。
|
// 获取身份信息。当 bGetSubPkgVer 为真,且打开的包为 AppxBundle 包,返回 AppxBundle 包中的某个应用包的版本号。
|
||||||
PKGREAD_API BOOL GetPackageIdentityVersion (_In_ HPKGREAD hReader, _Out_ VERSION *pVersion, _In_ BOOL bGetSubPkgVer _DEFAULT_INIT_VALUE_FORFUNC_ (0));
|
PKGREAD_API BOOL GetPackageIdentityVersion (_In_ HPKGREAD hReader, _Out_ VERSION *pVersion, _In_ BOOL bGetSubPkgVer _DEFAULT_INIT_VALUE_FORFUNC_ (0));
|
||||||
// 对于 AppxBundle 包,当传入的值有 PKG_IDENTITY_BUNDLE_GETAPPXINFO,则返回一个按位值,如 0b0011,则意味着支持 x86 和 x64
|
// 对于 AppxBundle 包,当传入的值有 PKG_IDENTITY_BUNDLE_GETAPPXINFO,则返回一个按位值,如 0b0011,则意味着支持 x86 和 x64
|
||||||
@@ -123,14 +141,21 @@ extern "C"
|
|||||||
// 传入参数参考:https://learn.microsoft.com/en-us/windows/win32/api/appxpackaging/nf-appxpackaging-iappxmanifestproperties-getstringvalue
|
// 传入参数参考:https://learn.microsoft.com/en-us/windows/win32/api/appxpackaging/nf-appxpackaging-iappxmanifestproperties-getstringvalue
|
||||||
// 可以使用宏 PKG_PROPERTIES_* 前缀的 DISPLAYNAME, DESCRIPTION, LOGO, PUBLISHER
|
// 可以使用宏 PKG_PROPERTIES_* 前缀的 DISPLAYNAME, DESCRIPTION, LOGO, PUBLISHER
|
||||||
PKGREAD_API LPWSTR GetPackagePropertiesStringValue (_In_ HPKGREAD hReader, _In_ LPCWSTR lpName);
|
PKGREAD_API LPWSTR GetPackagePropertiesStringValue (_In_ HPKGREAD hReader, _In_ LPCWSTR lpName);
|
||||||
|
#define GetPackagePropertiesDisplayName(_In_hReader_) GetPackagePropertiesStringValue (_In_hReader_, PKG_PROPERTIES_DISPLAYNAME)
|
||||||
|
#define GetPackagePropertiesDescription(_In_hReader_) GetPackagePropertiesStringValue (_In_hReader_, PKG_PROPERTIES_DESCRIPTION)
|
||||||
|
#define GetPackagePropertiesLogo(_In_hReader_) GetPackagePropertiesStringValue (_In_hReader_, PKG_PROPERTIES_LOGO)
|
||||||
|
#define GetPackagePropertiesPublisher(_In_hReader_) GetPackagePropertiesStringValue (_In_hReader_, PKG_PROPERTIES_PUBLISHER)
|
||||||
// 传入参数参考:https://learn.microsoft.com/zh-cn/windows/win32/api/appxpackaging/nf-appxpackaging-iappxmanifestproperties-getboolvalue
|
// 传入参数参考:https://learn.microsoft.com/zh-cn/windows/win32/api/appxpackaging/nf-appxpackaging-iappxmanifestproperties-getboolvalue
|
||||||
// 可以使用宏 PKG_PROPERTIES_* 前缀的 FRAMEWORD, IS_RESOURCE (Windows 8.1 支持)
|
// 可以使用宏 PKG_PROPERTIES_* 前缀的 FRAMEWORD, IS_RESOURCE (Windows 8.1 支持)
|
||||||
PKGREAD_API HRESULT GetPackagePropertiesBoolValue (_In_ HPKGREAD hReader, _In_ LPCWSTR lpName, _Outptr_ BOOL *pRet);
|
PKGREAD_API HRESULT GetPackagePropertiesBoolValue (_In_ HPKGREAD hReader, _In_ LPCWSTR lpName, _Outptr_ BOOL *pRet);
|
||||||
|
#define GetPackagePropertiesIsFramework(_In_hReader_, _Outptr_pRetValue_) GetPackagePropertiesBoolValue (_In_hReader_, PKG_PROPERTIES_FRAMEWORD, _Outptr_pRetValue_)
|
||||||
|
#define GetPackagePropertiesIsResourcePackage(_In_hReader_, _Outptr_pRetValue_) GetPackagePropertiesBoolValue (_In_hReader_, PKG_PROPERTIES_IS_RESOURCE, _Outptr_pRetValue_)
|
||||||
// Applications
|
// Applications
|
||||||
// 注意:由于读取 Application 在官方 API 中是枚举类型,只能枚举一次。
|
// 注意:由于读取 Application 在官方 API 中是枚举类型,只能枚举一次。
|
||||||
// 所以请预先安排好需要的信息,并在枚举时进行缓存。
|
// 所以请预先安排好需要的信息,并在枚举时进行缓存。
|
||||||
// 添加和删除的请参考这些:https://learn.microsoft.com/en-us/windows/win32/api/appxpackaging/nf-appxpackaging-iappxmanifestapplication-getstringvalue
|
// 添加和删除的请参考这些:https://learn.microsoft.com/en-us/windows/win32/api/appxpackaging/nf-appxpackaging-iappxmanifestapplication-getstringvalue
|
||||||
// DLL 本身支持:Id, DisplayName, BackgroundColor, ForegroundText, ShortName, Square44x44Logo
|
// DLL 本身支持:Id, DisplayName, BackgroundColor, ForegroundText, ShortName, Square44x44Logo
|
||||||
|
// 注:一定会保留项:AppUserModelID。这是必须项。
|
||||||
PKGREAD_API BOOL AddPackageApplicationItemGetName (_In_ LPCWSTR lpName);
|
PKGREAD_API BOOL AddPackageApplicationItemGetName (_In_ LPCWSTR lpName);
|
||||||
// 移除不需要的信息项名。
|
// 移除不需要的信息项名。
|
||||||
PKGREAD_API BOOL RemovePackageApplicationItemGetName (_In_ LPCWSTR lpName);
|
PKGREAD_API BOOL RemovePackageApplicationItemGetName (_In_ LPCWSTR lpName);
|
||||||
@@ -220,65 +245,12 @@ extern "C"
|
|||||||
#define DestroyCapabilitiesList DestroyWStringList
|
#define DestroyCapabilitiesList DestroyWStringList
|
||||||
#define DestroyDeviceCapabilitiesList DestroyWStringList
|
#define DestroyDeviceCapabilitiesList DestroyWStringList
|
||||||
|
|
||||||
#if defined (__cplusplus) && defined (PKGREAD_EXPORTS)
|
// Prerequisite
|
||||||
#include <cstdlib>
|
#define PKG_PREREQUISITE_OS_MIN_VERSION L"OSMinVersion"
|
||||||
#include <string>
|
#define PKG_PREREQUISITE_OS_MAX_VERSION_TESTED L"OSMaxVersionTested"
|
||||||
#include <functional>
|
PKGREAD_API BOOL GetPackagePrerequisite (_In_ HPKGREAD hReader, _In_ LPCWSTR lpName, _Outptr_ VERSION *pVerRet);
|
||||||
class package_info
|
#define GetPackagePrerequisiteOsMinVersion(_In_hReader_, _Outptr_pVerRet_) GetPackagePrerequisite (_In_hReader_, PKG_PREREQUISITE_OS_MIN_VERSION, _Outptr_pVerRet_)
|
||||||
{
|
#define GetPackagePrerequisiteOsMaxVersionTested(_In_hReader_, _Outptr_pVerRet_) GetPackagePrerequisite (_In_hReader_, PKG_PREREQUISITE_OS_MAX_VERSION_TESTED, _Outptr_pVerRet_)
|
||||||
private:
|
|
||||||
HPKGREAD hReader = nullptr;
|
|
||||||
std::wstring filepath = L"";
|
|
||||||
struct deconstr
|
|
||||||
{
|
|
||||||
std::function <void ()> endtask = nullptr;
|
|
||||||
deconstr (std::function <void ()> pf): endtask (pf) {}
|
|
||||||
~deconstr () { if (endtask) endtask (); }
|
|
||||||
};
|
|
||||||
public:
|
|
||||||
class identity
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
HPKGREAD &hReader;
|
|
||||||
public:
|
|
||||||
identity (HPKGREAD hReader): hReader (hReader) {}
|
|
||||||
std::wstring string_value (DWORD dwName) const
|
|
||||||
{
|
|
||||||
LPWSTR lpstr = nullptr;
|
|
||||||
deconstr rel ([&lpstr] () {
|
|
||||||
if (lpstr) free (lpstr);
|
|
||||||
lpstr = nullptr;
|
|
||||||
});
|
|
||||||
lpstr = GetPackageIdentityStringValue (hReader, dwName);
|
|
||||||
return lpstr;
|
|
||||||
}
|
|
||||||
VERSION version (bool read_subpkg_ver = false) const
|
|
||||||
{
|
|
||||||
VERSION ver;
|
|
||||||
GetPackageIdentityVersion (hReader, &ver, read_subpkg_ver);
|
|
||||||
return ver;
|
|
||||||
}
|
|
||||||
DWORD architecture () const
|
|
||||||
{
|
|
||||||
DWORD dw = 0;
|
|
||||||
GetPackageIdentityArchitecture (hReader, &dw);
|
|
||||||
return dw;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
package_info (): hReader (CreatePackageReader ()) {}
|
|
||||||
~package_info () { DestroyPackageReader (hReader); hReader = nullptr; }
|
|
||||||
std::wstring file () const { return filepath; }
|
|
||||||
bool file (const std::wstring &path)
|
|
||||||
{
|
|
||||||
return LoadPackageFromFile (hReader, (filepath = path).c_str ());
|
|
||||||
}
|
|
||||||
WORD package_type () const { return GetPackageType (hReader); }
|
|
||||||
bool valid () const { return hReader && IsPackageValid (hReader); }
|
|
||||||
WORD package_role () const { return GetPackageRole (hReader); }
|
|
||||||
identity get_identity () const { return identity (hReader); }
|
|
||||||
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _DEFAULT_INIT_VALUE_
|
#ifdef _DEFAULT_INIT_VALUE_
|
||||||
#undef _DEFAULT_INIT_VALUE_
|
#undef _DEFAULT_INIT_VALUE_
|
||||||
@@ -290,4 +262,332 @@ extern "C"
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#if defined (__cplusplus) && !defined (PKGREAD_EXPORTS)
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include <functional>
|
||||||
|
#include <cstring>
|
||||||
|
class package_reader
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
HPKGREAD hReader = nullptr;
|
||||||
|
std::wstring filepath = L"";
|
||||||
|
struct deconstr
|
||||||
|
{
|
||||||
|
std::function <void ()> endtask = nullptr;
|
||||||
|
deconstr (std::function <void ()> pf): endtask (pf) {}
|
||||||
|
~deconstr () { if (endtask) endtask (); }
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
class base_subitems
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
HPKGREAD &hReader;
|
||||||
|
public:
|
||||||
|
base_subitems (HPKGREAD &hReader): hReader (hReader) {}
|
||||||
|
};
|
||||||
|
class identity: public base_subitems
|
||||||
|
{
|
||||||
|
using base = base_subitems;
|
||||||
|
public:
|
||||||
|
using base::base;
|
||||||
|
std::wstring string_value (DWORD dwName) const
|
||||||
|
{
|
||||||
|
LPWSTR lpstr = nullptr;
|
||||||
|
deconstr rel ([&lpstr] () {
|
||||||
|
if (lpstr) free (lpstr);
|
||||||
|
lpstr = nullptr;
|
||||||
|
});
|
||||||
|
lpstr = GetPackageIdentityStringValue (hReader, dwName);
|
||||||
|
return lpstr ? lpstr : L"";
|
||||||
|
}
|
||||||
|
std::wstring name () const { return string_value (PKG_IDENTITY_NAME); }
|
||||||
|
std::wstring publisher () const { return string_value (PKG_IDENTITY_PUBLISHER); }
|
||||||
|
std::wstring package_family_name () const { return string_value (PKG_IDENTITY_PACKAGEFAMILYNAME); }
|
||||||
|
std::wstring package_full_name () const { return string_value (PKG_IDENTITY_PACKAGEFULLNAME); }
|
||||||
|
std::wstring resource_id () const { return string_value (PKG_IDENTITY_RESOURCEID); }
|
||||||
|
VERSION version (bool read_subpkg_ver = false) const { VERSION ver; GetPackageIdentityVersion (hReader, &ver, read_subpkg_ver); return ver; }
|
||||||
|
DWORD architecture () const { DWORD dw = 0; GetPackageIdentityArchitecture (hReader, &dw); return dw; }
|
||||||
|
};
|
||||||
|
class properties: public base_subitems
|
||||||
|
{
|
||||||
|
using base = base_subitems;
|
||||||
|
public:
|
||||||
|
using base::base;
|
||||||
|
std::wstring string_value (const std::wstring &swName) const
|
||||||
|
{
|
||||||
|
LPWSTR lpstr = nullptr;
|
||||||
|
deconstr rel ([&lpstr] () {
|
||||||
|
if (lpstr) free (lpstr);
|
||||||
|
lpstr = nullptr;
|
||||||
|
});
|
||||||
|
lpstr = GetPackagePropertiesStringValue (hReader, swName.c_str ());
|
||||||
|
return lpstr ? lpstr : L"";
|
||||||
|
}
|
||||||
|
bool bool_value (const std::wstring &swName, bool bRetWhenFailed = false) const
|
||||||
|
{
|
||||||
|
BOOL ret = FALSE;
|
||||||
|
HRESULT hr = GetPackagePropertiesBoolValue (hReader, swName.c_str (), &ret);
|
||||||
|
if (FAILED (hr)) return bRetWhenFailed;
|
||||||
|
else return ret != FALSE;
|
||||||
|
}
|
||||||
|
std::wstring display_name () const { return string_value (PKG_PROPERTIES_DISPLAYNAME); }
|
||||||
|
std::wstring publisher_display_name () const { return string_value (PKG_PROPERTIES_PUBLISHER); }
|
||||||
|
std::wstring description () const { return string_value (PKG_PROPERTIES_DESCRIPTION); }
|
||||||
|
std::wstring logo () const { return string_value (PKG_PROPERTIES_LOGO); }
|
||||||
|
bool framework () const { return bool_value (PKG_PROPERTIES_FRAMEWORD); }
|
||||||
|
bool resource_package () const { return bool_value (PKG_PROPERTIES_IS_RESOURCE); }
|
||||||
|
};
|
||||||
|
class application: public std::map <std::wstring, std::wstring>
|
||||||
|
{
|
||||||
|
using base = std::map <std::wstring, std::wstring>;
|
||||||
|
public:
|
||||||
|
using base::base;
|
||||||
|
std::wstring user_model_id () const { return this->find (L"AppUserModelID")->second; }
|
||||||
|
friend bool operator == (const application &a1, const application &a2) { return !_wcsicmp (a1.user_model_id ().c_str (), a2.user_model_id ().c_str ()); }
|
||||||
|
friend bool operator != (const application &a1, const application &a2) { return _wcsicmp (a1.user_model_id ().c_str (), a2.user_model_id ().c_str ()); }
|
||||||
|
explicit operator bool () const { return this->user_model_id ().empty (); }
|
||||||
|
std::wstring &operator [] (const std::wstring &key)
|
||||||
|
{
|
||||||
|
auto it = this->find (key);
|
||||||
|
if (it == this->end ())
|
||||||
|
{
|
||||||
|
it = this->insert (std::make_pair (key, L"")).first;
|
||||||
|
}
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
typename base::iterator find_case_insensitive (const std::wstring &key)
|
||||||
|
{
|
||||||
|
for (auto it = this->begin (); it != this->end (); ++it)
|
||||||
|
{
|
||||||
|
if (_wcsicmp (it->first.c_str (), key.c_str ()) == 0)
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
return this->end ();
|
||||||
|
}
|
||||||
|
typename base::const_iterator find_case_insensitive (const std::wstring &key) const
|
||||||
|
{
|
||||||
|
for (auto it = this->begin (); it != this->end (); ++ it)
|
||||||
|
{
|
||||||
|
if (_wcsicmp (it->first.c_str (), key.c_str ()) == 0)
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
return this->end ();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class applications
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
HPKGREAD &hReader;
|
||||||
|
HAPPENUMERATOR hList = nullptr;
|
||||||
|
public:
|
||||||
|
applications (HPKGREAD &hReader): hReader (hReader)
|
||||||
|
{
|
||||||
|
hList = GetPackageApplications (hReader);
|
||||||
|
}
|
||||||
|
~applications ()
|
||||||
|
{
|
||||||
|
if (hList) DestroyPackageApplications (hList);
|
||||||
|
hList = nullptr;
|
||||||
|
}
|
||||||
|
size_t get (std::vector <application> &apps)
|
||||||
|
{
|
||||||
|
apps.clear ();
|
||||||
|
if (!hList) return 0;
|
||||||
|
HLIST_PVOID hMapList = ApplicationsToMap (hList);
|
||||||
|
deconstr endt ([&hMapList] {
|
||||||
|
if (hMapList) DestroyApplicationsMap (hMapList);
|
||||||
|
hMapList = nullptr;
|
||||||
|
});
|
||||||
|
if (!hMapList) return 0;
|
||||||
|
for (size_t i = 0; i < hMapList->dwSize; i ++)
|
||||||
|
{
|
||||||
|
HLIST_PVOID &hKeyValues = ((HLIST_PVOID *)hMapList->alpVoid) [i];
|
||||||
|
application app;
|
||||||
|
for (size_t j = 0; j < hKeyValues->dwSize; j ++)
|
||||||
|
{
|
||||||
|
HPAIR_PVOID &hPair = ((HPAIR_PVOID *)hKeyValues->alpVoid) [j];
|
||||||
|
LPWSTR lpKey = (LPWSTR)hPair->lpKey;
|
||||||
|
LPWSTR lpValue = (LPWSTR)hPair->lpValue;
|
||||||
|
if (!lpKey || !*lpKey) continue;
|
||||||
|
app [lpKey] = lpValue ? lpValue : L"";
|
||||||
|
}
|
||||||
|
apps.push_back (app);
|
||||||
|
}
|
||||||
|
return apps.size ();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class capabilities: public base_subitems
|
||||||
|
{
|
||||||
|
using base = base_subitems;
|
||||||
|
public:
|
||||||
|
using base::base;
|
||||||
|
size_t capabilities_name (std::vector <std::wstring> &output) const
|
||||||
|
{
|
||||||
|
output.clear ();
|
||||||
|
HLIST_PVOID hList = GetCapabilitiesList (hReader);
|
||||||
|
deconstr endt ([&hList] () {
|
||||||
|
if (hList) DestroyCapabilitiesList (hList);
|
||||||
|
hList = nullptr;
|
||||||
|
});
|
||||||
|
if (!hList) return 0;
|
||||||
|
for (size_t i = 0; i < hList->dwSize; i ++)
|
||||||
|
{
|
||||||
|
LPWSTR lpstr = (LPWSTR)hList->alpVoid [i];
|
||||||
|
if (!lpstr) continue;
|
||||||
|
output.push_back (lpstr);
|
||||||
|
}
|
||||||
|
return output.size ();
|
||||||
|
}
|
||||||
|
size_t device_capabilities (std::vector <std::wstring> &output) const
|
||||||
|
{
|
||||||
|
output.clear ();
|
||||||
|
HLIST_PVOID hList = GetDeviceCapabilitiesList (hReader);
|
||||||
|
deconstr endt ([&hList] () {
|
||||||
|
if (hList) DestroyDeviceCapabilitiesList (hList);
|
||||||
|
hList = nullptr;
|
||||||
|
});
|
||||||
|
if (!hList) return 0;
|
||||||
|
for (size_t i = 0; i < hList->dwSize; i ++)
|
||||||
|
{
|
||||||
|
LPWSTR lpstr = (LPWSTR)hList->alpVoid [i];
|
||||||
|
if (!lpstr) continue;
|
||||||
|
output.push_back (lpstr);
|
||||||
|
}
|
||||||
|
return output.size ();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct dependency
|
||||||
|
{
|
||||||
|
std::wstring name, publisher;
|
||||||
|
VERSION vermin;
|
||||||
|
dependency (const std::wstring &name = L"", const std::wstring &pub = L"", const VERSION &ver = VERSION ()):
|
||||||
|
name (name), publisher (pub), vermin (ver) {}
|
||||||
|
};
|
||||||
|
class dependencies: public base_subitems
|
||||||
|
{
|
||||||
|
using base = base_subitems;
|
||||||
|
public:
|
||||||
|
using base::base;
|
||||||
|
size_t get (std::vector <dependency> &output) const
|
||||||
|
{
|
||||||
|
auto hList = GetDependencesInfoList (hReader);
|
||||||
|
deconstr rel ([&hList] () {
|
||||||
|
DestroyDependencesInfoList (hList);
|
||||||
|
});
|
||||||
|
if (!hList) return 0;
|
||||||
|
for (size_t i = 0; i < hList->dwSize; i ++)
|
||||||
|
{
|
||||||
|
DEPENDENCY_INFO &depinf = ((DEPENDENCY_INFO *)hList->aDepInfo) [i];
|
||||||
|
if (!depinf.lpName || !*depinf.lpName) continue;
|
||||||
|
output.push_back (dependency (depinf.lpName, depinf.lpPublisher ? depinf.lpPublisher : L"", depinf.verMin));
|
||||||
|
}
|
||||||
|
return output.size ();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class resources: public base_subitems
|
||||||
|
{
|
||||||
|
using base = base_subitems;
|
||||||
|
public:
|
||||||
|
using base::base;
|
||||||
|
size_t languages (std::vector <std::wstring> &langs) const
|
||||||
|
{
|
||||||
|
langs.clear ();
|
||||||
|
auto hList = GetResourcesLanguages (hReader);
|
||||||
|
deconstr rel ([&hList] () {
|
||||||
|
if (hList) DestroyResourcesLanguagesList (hList);
|
||||||
|
hList = nullptr;
|
||||||
|
});
|
||||||
|
if (!hList) return 0;
|
||||||
|
for (size_t i = 0; i < hList->dwSize; i ++)
|
||||||
|
{
|
||||||
|
LPWSTR lpstr = ((LPWSTR *)hList->alpVoid) [i];
|
||||||
|
if (lpstr && *lpstr) langs.push_back (std::wstring (lpstr));
|
||||||
|
}
|
||||||
|
return langs.size ();
|
||||||
|
}
|
||||||
|
size_t languages (std::vector <LCID> &langs) const
|
||||||
|
{
|
||||||
|
langs.clear ();
|
||||||
|
auto hList = GetResourcesLanguagesToLcid (hReader);
|
||||||
|
deconstr rel ([&hList] () {
|
||||||
|
if (hList) DestroyResourcesLanguagesLcidList (hList);
|
||||||
|
hList = nullptr;
|
||||||
|
});
|
||||||
|
if (!hList) return 0;
|
||||||
|
for (size_t i = 0; i < hList->dwSize; i ++)
|
||||||
|
{
|
||||||
|
if (hList->aLcid [i]) langs.push_back (hList->aLcid [i]);
|
||||||
|
}
|
||||||
|
return langs.size ();
|
||||||
|
}
|
||||||
|
size_t scales (std::vector <UINT32> &output) const
|
||||||
|
{
|
||||||
|
output.clear ();
|
||||||
|
auto hList = GetResourcesScales (hReader);
|
||||||
|
deconstr rel ([&hList] () {
|
||||||
|
if (hList) DestroyResourcesScalesList (hList);
|
||||||
|
});
|
||||||
|
if (!hList) return 0;
|
||||||
|
for (size_t i = 0; i < hList->dwSize; i ++)
|
||||||
|
{
|
||||||
|
UINT32 s = hList->aUI32 [i];
|
||||||
|
if (s) output.push_back (s);
|
||||||
|
}
|
||||||
|
return output.size ();
|
||||||
|
}
|
||||||
|
DWORD dx_feature_level () const { return GetResourcesDxFeatureLevels (hReader); }
|
||||||
|
// 向数组添加的是以 PKG_RESOURCES_DXFEATURE_* 前缀的常量
|
||||||
|
size_t dx_feature_level (std::vector <DWORD> &ret)
|
||||||
|
{
|
||||||
|
DWORD dx = dx_feature_level ();
|
||||||
|
if (dx & PKG_RESOURCES_DXFEATURE_LEVEL9) ret.push_back (PKG_RESOURCES_DXFEATURE_LEVEL9);
|
||||||
|
else if (dx & PKG_RESOURCES_DXFEATURE_LEVEL10) ret.push_back (PKG_RESOURCES_DXFEATURE_LEVEL10);
|
||||||
|
else if (dx & PKG_RESOURCES_DXFEATURE_LEVEL11) ret.push_back (PKG_RESOURCES_DXFEATURE_LEVEL11);
|
||||||
|
else if (dx & PKG_RESOURCES_DXFEATURE_LEVEL12) ret.push_back (PKG_RESOURCES_DXFEATURE_LEVEL12);
|
||||||
|
return ret.size ();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class prerequisites: public base_subitems
|
||||||
|
{
|
||||||
|
using base = base_subitems;
|
||||||
|
public:
|
||||||
|
using base::base;
|
||||||
|
VERSION get_version (const std::wstring &name) const
|
||||||
|
{
|
||||||
|
VERSION ver;
|
||||||
|
GetPackagePrerequisite (hReader, name.c_str (), &ver);
|
||||||
|
return ver;
|
||||||
|
}
|
||||||
|
VERSION os_min_version () const { return get_version (PKG_PREREQUISITE_OS_MIN_VERSION); }
|
||||||
|
VERSION os_max_version_tested () const { return get_version (PKG_PREREQUISITE_OS_MAX_VERSION_TESTED); }
|
||||||
|
};
|
||||||
|
package_reader (): hReader (CreatePackageReader ()) {}
|
||||||
|
package_reader (const std::wstring &fpath): hReader (CreatePackageReader ())
|
||||||
|
{
|
||||||
|
file (fpath);
|
||||||
|
}
|
||||||
|
~package_reader () { DestroyPackageReader (hReader); hReader = nullptr; }
|
||||||
|
std::wstring file () const { return filepath; }
|
||||||
|
bool file (const std::wstring &path)
|
||||||
|
{
|
||||||
|
return LoadPackageFromFile (hReader, (filepath = path).c_str ());
|
||||||
|
}
|
||||||
|
// PKGTYPE_* 前缀常量
|
||||||
|
WORD package_type () const { return GetPackageType (hReader); }
|
||||||
|
bool valid () const { return hReader && IsPackageValid (hReader); }
|
||||||
|
// PKGROLE_* 前缀常量
|
||||||
|
WORD package_role () const { return GetPackageRole (hReader); }
|
||||||
|
identity get_identity () { return identity (hReader); }
|
||||||
|
properties get_properties () { return properties (hReader); }
|
||||||
|
applications get_applications () { return applications (hReader); }
|
||||||
|
capabilities get_capabilities () { return capabilities (hReader); }
|
||||||
|
dependencies get_dependencies () { return dependencies (hReader); }
|
||||||
|
resources get_resources () { return resources (hReader); }
|
||||||
|
prerequisites get_prerequisites () { return prerequisites (hReader); }
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -512,7 +512,6 @@ namespace appx_info
|
|||||||
appx_preq (IAppxManifestReader *ptr = nullptr): com_info (nullptr) { set (ptr); }
|
appx_preq (IAppxManifestReader *ptr = nullptr): com_info (nullptr) { set (ptr); }
|
||||||
version os_min_version () const { return get_version (L"OSMinVersion"); }
|
version os_min_version () const { return get_version (L"OSMinVersion"); }
|
||||||
version os_max_version_tested () const { return get_version (L"OSMaxVersionTested"); }
|
version os_max_version_tested () const { return get_version (L"OSMaxVersionTested"); }
|
||||||
private:
|
|
||||||
version get_version (const std::wstring &name) const
|
version get_version (const std::wstring &name) const
|
||||||
{
|
{
|
||||||
UINT64 u64 = 0;
|
UINT64 u64 = 0;
|
||||||
@@ -551,8 +550,10 @@ namespace appx_info
|
|||||||
if (lpstr) CoTaskMemFree (lpstr);
|
if (lpstr) CoTaskMemFree (lpstr);
|
||||||
lpstr = nullptr;
|
lpstr = nullptr;
|
||||||
});
|
});
|
||||||
if (SUCCEEDED (p->GetStringValue (it.c_str (), &lpstr))) app [it] = lpstr;
|
if (std::wnstring (it) == std::wnstring (L"AppUserModelID")) continue;
|
||||||
else app [it] = nullptr;
|
if (SUCCEEDED (p->GetStringValue (it.c_str (), &lpstr)) && lpstr)
|
||||||
|
app [it] = lpstr;
|
||||||
|
else app [it] = std::wstring ();
|
||||||
}
|
}
|
||||||
return app;
|
return app;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ static CriticalSection g_appcs;
|
|||||||
bool PushApplicationAttributeItem (const std::wstring &lpstr)
|
bool PushApplicationAttributeItem (const std::wstring &lpstr)
|
||||||
{
|
{
|
||||||
CreateScopedLock (g_appcs);
|
CreateScopedLock (g_appcs);
|
||||||
|
if (std::wnstring (L"AppUserModelID") == lpstr) return false;
|
||||||
size_t len1 = appitems.size ();
|
size_t len1 = appitems.size ();
|
||||||
push_unique <std::wstring> (appitems, lpstr, [] (const std::wstring &v1, const std::wstring &v2) -> bool {
|
push_unique <std::wstring> (appitems, lpstr, [] (const std::wstring &v1, const std::wstring &v2) -> bool {
|
||||||
return std::wnstring (v1) == std::wnstring (v2);
|
return std::wnstring (v1) == std::wnstring (v2);
|
||||||
@@ -111,6 +112,7 @@ bool PushApplicationAttributeItem (const std::wstring &lpstr)
|
|||||||
bool RemoveApplicationAttributeItem (const std::wstring &lpstr)
|
bool RemoveApplicationAttributeItem (const std::wstring &lpstr)
|
||||||
{
|
{
|
||||||
CreateScopedLock (g_appcs);
|
CreateScopedLock (g_appcs);
|
||||||
|
if (std::wnstring (L"AppUserModelID") == lpstr) return false;
|
||||||
auto it = std::find_if (appitems.begin (), appitems.end (), [&] (const std::wstring &v) {
|
auto it = std::find_if (appitems.begin (), appitems.end (), [&] (const std::wstring &v) {
|
||||||
return std::wnstring (v) == std::wnstring (lpstr);
|
return std::wnstring (v) == std::wnstring (lpstr);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,26 +1,26 @@
|
|||||||
========================================================================
|
========================================================================
|
||||||
动态链接库:prireader 项目概述
|
动态链接库:priread 项目概述
|
||||||
========================================================================
|
========================================================================
|
||||||
|
|
||||||
应用程序向导已为您创建了此 prireader DLL。
|
应用程序向导已为您创建了此 priread DLL。
|
||||||
|
|
||||||
本文件概要介绍组成 prireader 应用程序的每个文件的内容。
|
本文件概要介绍组成 priread 应用程序的每个文件的内容。
|
||||||
|
|
||||||
|
|
||||||
prireader.vcxproj
|
priread.vcxproj
|
||||||
这是使用应用程序向导生成的 VC++ 项目的主项目文件,其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。
|
这是使用应用程序向导生成的 VC++ 项目的主项目文件,其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。
|
||||||
|
|
||||||
prireader.vcxproj.filters
|
priread.vcxproj.filters
|
||||||
这是使用“应用程序向导”生成的 VC++ 项目筛选器文件。它包含有关项目文件与筛选器之间的关联信息。在 IDE 中,通过这种关联,在特定节点下以分组形式显示具有相似扩展名的文件。例如,“.cpp”文件与“源文件”筛选器关联。
|
这是使用“应用程序向导”生成的 VC++ 项目筛选器文件。它包含有关项目文件与筛选器之间的关联信息。在 IDE 中,通过这种关联,在特定节点下以分组形式显示具有相似扩展名的文件。例如,“.cpp”文件与“源文件”筛选器关联。
|
||||||
|
|
||||||
prireader.cpp
|
priread.cpp
|
||||||
这是主 DLL 源文件。
|
这是主 DLL 源文件。
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
其他标准文件:
|
其他标准文件:
|
||||||
|
|
||||||
StdAfx.h, StdAfx.cpp
|
StdAfx.h, StdAfx.cpp
|
||||||
这些文件用于生成名为 prireader.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。
|
这些文件用于生成名为 priread.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
其他注释:
|
其他注释:
|
||||||
141
priread/prifile.h
Normal file
141
priread/prifile.h
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <atlbase.h>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
struct destruct
|
||||||
|
{
|
||||||
|
std::function <void ()> endtask = nullptr;
|
||||||
|
destruct (std::function <void ()> init): endtask (init) {}
|
||||||
|
~destruct () { if (endtask) endtask (); }
|
||||||
|
};
|
||||||
|
typedef struct LargeInt
|
||||||
|
{
|
||||||
|
LARGE_INTEGER val;
|
||||||
|
LargeInt (LONGLONG v) { val.QuadPart = v; }
|
||||||
|
operator LARGE_INTEGER() const { return val; }
|
||||||
|
} lint;
|
||||||
|
|
||||||
|
struct head
|
||||||
|
{
|
||||||
|
CHAR szMagic [8] = {};
|
||||||
|
WORD wPlaceholder1 = -1, // 0
|
||||||
|
wPlaceholder2 = 0; // 1
|
||||||
|
DWORD dwFileSize = 0,
|
||||||
|
dwToCOffset = 0,
|
||||||
|
dwSectStartOffset = 0;
|
||||||
|
WORD wSectCount = 0,
|
||||||
|
wPlaceholder3 = 0; // 0xFFFF
|
||||||
|
DWORD dwPlaceholder4 = -1; // 0
|
||||||
|
bool valid ()
|
||||||
|
{
|
||||||
|
CHAR m7 = szMagic [7];
|
||||||
|
destruct endt ([this, m7] () {
|
||||||
|
if (m7) szMagic [7] = m7;
|
||||||
|
});
|
||||||
|
szMagic [7] = '\0';
|
||||||
|
if (!stricmp (szMagic, "mrm_pri")) return false;
|
||||||
|
switch (m7)
|
||||||
|
{
|
||||||
|
case '0': case '1': case 'f': case 'F': break;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
if (wPlaceholder1 != 0) return false;
|
||||||
|
if (wPlaceholder2 != 1) return false;
|
||||||
|
if (wPlaceholder3 != 0xFFFF) return false;
|
||||||
|
if (dwPlaceholder4 != 0) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct foot
|
||||||
|
{
|
||||||
|
DWORD dwChkCode = 0, // 0xDEFFFADE
|
||||||
|
dwTotalFileSize = 0;
|
||||||
|
CHAR szMagic [8] = {};
|
||||||
|
bool valid (const head &fh)
|
||||||
|
{
|
||||||
|
if (dwChkCode != 0xDEFFFADE) return false;
|
||||||
|
if (dwTotalFileSize != fh.dwFileSize) return false;
|
||||||
|
for (int i = 0; i < 8; i ++)
|
||||||
|
{
|
||||||
|
if (szMagic [i] != fh.szMagic [i] && tolower (szMagic [i]) != tolower (fh.szMagic [i])) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct tocentry
|
||||||
|
{
|
||||||
|
CHAR szIdentifier [16] = {0};
|
||||||
|
WORD wFlags = 0;
|
||||||
|
WORD wSectFlags = 0;
|
||||||
|
DWORD dwSectQualifier = 0;
|
||||||
|
DWORD dwSectOffset = 0;
|
||||||
|
DWORD dwSectLength = 0;
|
||||||
|
};
|
||||||
|
struct section_header
|
||||||
|
{
|
||||||
|
CHAR szIdentifier [16] = {0};
|
||||||
|
DWORD dwQualifier = 0;
|
||||||
|
WORD wFlags = 0;
|
||||||
|
DWORD dwLength = 0;
|
||||||
|
DWORD dwPlaceholder1 = -1; // 0
|
||||||
|
bool valid () const { return szIdentifier [0] && !dwPlaceholder1; }
|
||||||
|
};
|
||||||
|
struct section_check
|
||||||
|
{
|
||||||
|
DWORD dwChkCode = 0, // 0xDEF5FADE
|
||||||
|
dwSectLength = 0;
|
||||||
|
bool valid (const section_header &h) const { return dwChkCode == 0xDEF5FADE && dwSectLength == h.dwLength; }
|
||||||
|
};
|
||||||
|
struct substream
|
||||||
|
{
|
||||||
|
IStream *&ifile;
|
||||||
|
UINT64 offset = 0,
|
||||||
|
size = 0;
|
||||||
|
substream (IStream *&ifile, UINT64 ofs = 0, UINT64 siz = 0): ifile (ifile), offset (ofs), size (siz) {}
|
||||||
|
};
|
||||||
|
struct section
|
||||||
|
{
|
||||||
|
section_header head;
|
||||||
|
section_check foot;
|
||||||
|
substream childst;
|
||||||
|
};
|
||||||
|
class prifile
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
IStream *pfile = nullptr;
|
||||||
|
head header; foot footer;
|
||||||
|
std::vector <tocentry> toclist;
|
||||||
|
public:
|
||||||
|
bool load (IStream *ifile)
|
||||||
|
{
|
||||||
|
if (!ifile) return false;
|
||||||
|
header = head ();
|
||||||
|
footer = foot ();
|
||||||
|
ifile->Seek (lint (0), STREAM_SEEK_SET, nullptr);
|
||||||
|
DWORD dwhead = 0, dwfoot = 0;
|
||||||
|
ifile->Read (&header, sizeof (header), &dwhead);
|
||||||
|
if (!dwhead) return false;
|
||||||
|
if (!header.valid ()) return false;
|
||||||
|
ifile->Seek (lint (header.dwFileSize - 16), STREAM_SEEK_SET, nullptr);
|
||||||
|
ifile->Read (&footer, sizeof (footer), &dwfoot);
|
||||||
|
if (!dwfoot) return false;
|
||||||
|
if (!footer.valid (header)) return false;
|
||||||
|
pfile = ifile;
|
||||||
|
bool res = inittoc ();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool inittoc ()
|
||||||
|
{
|
||||||
|
toclist.clear ();
|
||||||
|
pfile->Seek (lint (header.dwToCOffset), STREAM_SEEK_SET, nullptr);
|
||||||
|
for (size_t i = 0; i < header.wSectCount; i ++)
|
||||||
|
{
|
||||||
|
tocentry toc;
|
||||||
|
DWORD dwRead;
|
||||||
|
pfile->Read (&toc, sizeof (toc), &dwRead);
|
||||||
|
toclist.push_back (toc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
22
priread/priread.cpp
Normal file
22
priread/priread.cpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
// priread.cpp : 定义 DLL 应用程序的导出函数。
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "priread.h"
|
||||||
|
|
||||||
|
|
||||||
|
// 这是导出变量的一个示例
|
||||||
|
PRIREAD_API int npriread=0;
|
||||||
|
|
||||||
|
// 这是导出函数的一个示例。
|
||||||
|
PRIREAD_API int fnpriread(void)
|
||||||
|
{
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 这是已导出类的构造函数。
|
||||||
|
// 有关类定义的信息,请参阅 priread.h
|
||||||
|
Cpriread::Cpriread()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
22
priread/priread.h
Normal file
22
priread/priread.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
// 下列 ifdef 块是创建使从 DLL 导出更简单的
|
||||||
|
// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 PRIREAD_EXPORTS
|
||||||
|
// 符号编译的。在使用此 DLL 的
|
||||||
|
// 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
|
||||||
|
// PRIREAD_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
|
||||||
|
// 符号视为是被导出的。
|
||||||
|
#ifdef PRIREAD_EXPORTS
|
||||||
|
#define PRIREAD_API __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define PRIREAD_API __declspec(dllimport)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 此类是从 priread.dll 导出的
|
||||||
|
class PRIREAD_API Cpriread {
|
||||||
|
public:
|
||||||
|
Cpriread(void);
|
||||||
|
// TODO: 在此添加您的方法。
|
||||||
|
};
|
||||||
|
|
||||||
|
extern PRIREAD_API int npriread;
|
||||||
|
|
||||||
|
PRIREAD_API int fnpriread(void);
|
||||||
@@ -19,9 +19,9 @@
|
|||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Globals">
|
<PropertyGroup Label="Globals">
|
||||||
<ProjectGuid>{D8CFAA98-0A77-4C5B-A61B-11EF44206712}</ProjectGuid>
|
<ProjectGuid>{99D714D9-F40D-425B-BAFA-8B41C17971A5}</ProjectGuid>
|
||||||
<Keyword>Win32Proj</Keyword>
|
<Keyword>Win32Proj</Keyword>
|
||||||
<RootNamespace>prireader</RootNamespace>
|
<RootNamespace>priread</RootNamespace>
|
||||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v120</PlatformToolset>
|
<PlatformToolset>v140</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -86,7 +86,7 @@
|
|||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;PRIREADER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;PRIREAD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
@@ -99,7 +99,7 @@
|
|||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;PRIREADER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;PRIREAD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
@@ -114,7 +114,7 @@
|
|||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PRIREADER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PRIREAD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
@@ -131,7 +131,7 @@
|
|||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;PRIREADER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;PRIREAD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
@@ -145,9 +145,8 @@
|
|||||||
<Text Include="ReadMe.txt" />
|
<Text Include="ReadMe.txt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="prifile.h" />
|
||||||
<ClInclude Include="priread.h" />
|
<ClInclude Include="priread.h" />
|
||||||
<ClInclude Include="prireader.h" />
|
|
||||||
<ClInclude Include="resource.h" />
|
|
||||||
<ClInclude Include="stdafx.h" />
|
<ClInclude Include="stdafx.h" />
|
||||||
<ClInclude Include="targetver.h" />
|
<ClInclude Include="targetver.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -166,7 +165,7 @@
|
|||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
</PrecompiledHeader>
|
</PrecompiledHeader>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="prireader.cpp" />
|
<ClCompile Include="priread.cpp" />
|
||||||
<ClCompile Include="stdafx.cpp">
|
<ClCompile Include="stdafx.cpp">
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||||
@@ -24,21 +24,18 @@
|
|||||||
<ClInclude Include="targetver.h">
|
<ClInclude Include="targetver.h">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="prireader.h">
|
|
||||||
<Filter>头文件</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="resource.h">
|
|
||||||
<Filter>头文件</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="priread.h">
|
<ClInclude Include="priread.h">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="prifile.h">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="stdafx.cpp">
|
<ClCompile Include="stdafx.cpp">
|
||||||
<Filter>源文件</Filter>
|
<Filter>源文件</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="prireader.cpp">
|
<ClCompile Include="priread.cpp">
|
||||||
<Filter>源文件</Filter>
|
<Filter>源文件</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="dllmain.cpp">
|
<ClCompile Include="dllmain.cpp">
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
// stdafx.cpp : 只包括标准包含文件的源文件
|
// stdafx.cpp : 只包括标准包含文件的源文件
|
||||||
// prireader.pch 将作为预编译头
|
// priread.pch 将作为预编译头
|
||||||
// stdafx.obj 将包含预编译类型信息
|
// stdafx.obj 将包含预编译类型信息
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
|
||||||
// TODO: 在 STDAFX.H 中引用任何所需的附加头文件,
|
// TODO: 在 STDAFX.H 中引用任何所需的附加头文件,
|
||||||
//而不是在此文件中引用
|
//而不是在此文件中引用
|
||||||
@@ -18,4 +18,3 @@
|
|||||||
#include <atlstr.h>
|
#include <atlstr.h>
|
||||||
|
|
||||||
// TODO: 在此处引用程序需要的其他头文件
|
// TODO: 在此处引用程序需要的其他头文件
|
||||||
#include <winres.h>
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
// prireader.cpp : 定义 DLL 应用程序的导出函数。
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
#include "prireader.h"
|
|
||||||
|
|
||||||
|
|
||||||
// 这是导出变量的一个示例
|
|
||||||
PRIREADER_API int nprireader=0;
|
|
||||||
|
|
||||||
// 这是导出函数的一个示例。
|
|
||||||
PRIREADER_API int fnprireader(void)
|
|
||||||
{
|
|
||||||
return 42;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 这是已导出类的构造函数。
|
|
||||||
// 有关类定义的信息,请参阅 prireader.h
|
|
||||||
Cprireader::Cprireader()
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
// 下列 ifdef 块是创建使从 DLL 导出更简单的
|
|
||||||
// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 PRIREADER_EXPORTS
|
|
||||||
// 符号编译的。在使用此 DLL 的
|
|
||||||
// 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
|
|
||||||
// PRIREADER_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
|
|
||||||
// 符号视为是被导出的。
|
|
||||||
#ifdef PRIREADER_EXPORTS
|
|
||||||
#define PRIREADER_API __declspec(dllexport)
|
|
||||||
#else
|
|
||||||
#define PRIREADER_API __declspec(dllimport)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// 此类是从 prireader.dll 导出的
|
|
||||||
class PRIREADER_API Cprireader {
|
|
||||||
public:
|
|
||||||
Cprireader(void);
|
|
||||||
// TODO: 在此添加您的方法。
|
|
||||||
};
|
|
||||||
|
|
||||||
extern PRIREADER_API int nprireader;
|
|
||||||
|
|
||||||
PRIREADER_API int fnprireader(void);
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
//{{NO_DEPENDENCIES}}
|
|
||||||
// Microsoft Visual C++ generated include file.
|
|
||||||
// Used by prireader.rc
|
|
||||||
|
|
||||||
// 新对象的下一组默认值
|
|
||||||
//
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
|
||||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
|
||||||
#define _APS_NEXT_SYMED_VALUE 101
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
Reference in New Issue
Block a user