Fix decoding problems and add support for unpacking large files on Windows (#221)

* Always decode file names; Fix encoding array; Support large files on Windows

* Remove variable decodedFileName

* Fixed formatting of EncodingToChar array

* Removed whitespace
This commit is contained in:
stephenk-msft 2019-09-25 13:25:49 -07:00 коммит произвёл GitHub
Родитель 4f4f8ca942
Коммит 1389e84cbb
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 14 добавлений и 10 удалений

Просмотреть файл

@ -43,7 +43,7 @@ namespace MSIX {
#ifdef WIN32
static const wchar_t* modes[] = { L"rb", L"wb", L"ab", L"r+b", L"w+b", L"a+b" };
errno_t err = _wfopen_s(&m_file, name.c_str(), modes[mode]);
ThrowErrorIfNot(Error::FileOpen, (err==0), std::string("file: " + m_name + " does not exist.").c_str());
ThrowErrorIfNot(Error::FileOpen, (err==0), std::string("file: " + m_name + " does not exist.").c_str());
#else
static const char* modes[] = { "rb", "wb", "ab", "r+b", "w+b", "a+b" };
m_file = std::fopen(m_name.c_str(), modes[mode]);
@ -74,7 +74,11 @@ namespace MSIX {
// IStream
HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER move, DWORD origin, ULARGE_INTEGER* newPosition) noexcept override try
{
#ifdef WIN32
int rc = _fseeki64(m_file, move.QuadPart, origin);
#else
int rc = std::fseek(m_file, static_cast<long>(move.QuadPart), origin);
#endif
ThrowErrorIfNot(Error::FileSeek, (rc == 0), "seek failed");
m_offset = Ftell();
if (newPosition) { newPosition->QuadPart = m_offset; }
@ -111,7 +115,11 @@ namespace MSIX {
inline std::uint64_t Ftell()
{
#ifdef WIN32
auto result = _ftelli64(m_file);
#else
auto result = std::ftell(m_file);
#endif
return static_cast<std::uint64_t>(result);
}

Просмотреть файл

@ -136,9 +136,9 @@ namespace MSIX { namespace Encoding {
const EncodingChar EncodingToChar[] =
{ EncodingChar(L"20", ' '), EncodingChar(L"21", '!'), EncodingChar(L"23", '#'), EncodingChar(L"24", '$'),
EncodingChar(L"25", '%'), EncodingChar(L"26", '&'), EncodingChar(L"27", '\''), EncodingChar(L"28", '('),
EncodingChar(L"29", ')'), EncodingChar(L"25", '+'), EncodingChar(L"2B", '%'), EncodingChar(L"2C", ','),
EncodingChar(L"3B", ';'), EncodingChar(L"3D", '='), EncodingChar(L"40", '@'), EncodingChar(L"5B", '['),
EncodingChar(L"5D", ']'), EncodingChar(L"7B", '{'), EncodingChar(L"7D", '}')
EncodingChar(L"29", ')'), EncodingChar(L"2B", '+'), EncodingChar(L"2C", ','), EncodingChar(L"3B", ';'),
EncodingChar(L"3D", '='), EncodingChar(L"40", '@'), EncodingChar(L"5B", '['), EncodingChar(L"5D", ']'),
EncodingChar(L"5E", '^'), EncodingChar(L"60", '`'), EncodingChar(L"7B", '{'), EncodingChar(L"7D", '}')
};
// Convert a single hex digit to its corresponding value

Просмотреть файл

@ -401,7 +401,7 @@ namespace MSIX {
auto file = std::find(std::begin(m_applicablePackagesNames), std::end(m_applicablePackagesNames), fileName);
if (file == std::end(m_applicablePackagesNames))
{
std::string targetName;
std::string targetName = Encoding::DecodeFileName(fileName);
if ((options & MSIX_PACKUNPACK_OPTION_CREATEPACKAGESUBFOLDER) || options & MSIX_PACKUNPACK_OPTION_UNPACKWITHFLATSTRUCTURE)
{
ComPtr<IAppxManifestPackageId> packageId;
@ -419,11 +419,7 @@ namespace MSIX {
// by looking at "/" in the string. If to->GetPathSeparator() is used the subfolder with
// the package full name won't be created on Windows, but it will on other platforms.
// This means that we have different behaviors in non-Win platforms.
targetName = packageId.As<IAppxManifestPackageIdInternal>()->GetPackageFullName() + "/" + fileName;
}
else
{
targetName = Encoding::DecodeFileName(fileName);
targetName = packageId.As<IAppxManifestPackageIdInternal>()->GetPackageFullName() + "/" + targetName;
}
auto deleteFile = MSIX::scope_exit([&targetName]