mirror of
https://github.com/chibicitiberiu/rainmeter-studio.git
synced 2024-02-24 04:33:31 +00:00
SkinInstaller/SkinPackager: Fix Unicode filename handling
Existing .rmskin files need to be repackaged for proper Unicode filename support. Non-ASCII filenames can be used only if 'Minimum Rainmeter' is set to at least '3.0.1'. An error will be displayed otherwise.
This commit is contained in:
parent
d6e26401ca
commit
d087a7db42
@ -405,11 +405,14 @@ bool DialogInstall::ReadPackage()
|
|||||||
// Helper to sets buffer with current file name
|
// Helper to sets buffer with current file name
|
||||||
auto getFileInfo = [&]()->bool
|
auto getFileInfo = [&]()->bool
|
||||||
{
|
{
|
||||||
char cBuffer[MAX_PATH];
|
char cBuffer[MAX_PATH * 3];
|
||||||
unz_file_info ufi;
|
unz_file_info ufi;
|
||||||
if (unzGetCurrentFileInfo(m_PackageUnzFile, &ufi, cBuffer, MAX_PATH, nullptr, 0, nullptr, 0) == UNZ_OK)
|
if (unzGetCurrentFileInfo(
|
||||||
|
m_PackageUnzFile, &ufi, cBuffer, _countof(cBuffer), nullptr, 0, nullptr, 0) == UNZ_OK)
|
||||||
{
|
{
|
||||||
MultiByteToWideChar(CP_ACP, 0, cBuffer, strlen(cBuffer) + 1, buffer, MAX_PATH);
|
const uLong ZIP_UTF8_FLAG = 1 << 11;
|
||||||
|
const DWORD codePage = (ufi.flag & ZIP_UTF8_FLAG) ? CP_UTF8 : CP_ACP;
|
||||||
|
MultiByteToWideChar(codePage, 0, cBuffer, strlen(cBuffer) + 1, buffer, MAX_PATH);
|
||||||
while (WCHAR* pos = wcschr(buffer, L'/')) *pos = L'\\';
|
while (WCHAR* pos = wcschr(buffer, L'/')) *pos = L'\\';
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -713,11 +716,14 @@ bool DialogInstall::InstallPackage()
|
|||||||
// Helper to sets buffer with current file name
|
// Helper to sets buffer with current file name
|
||||||
auto getFileInfo = [&]()->bool
|
auto getFileInfo = [&]()->bool
|
||||||
{
|
{
|
||||||
char cBuffer[MAX_PATH];
|
char cBuffer[MAX_PATH * 3];
|
||||||
unz_file_info ufi;
|
unz_file_info ufi;
|
||||||
if (unzGetCurrentFileInfo(m_PackageUnzFile, &ufi, cBuffer, MAX_PATH, nullptr, 0, nullptr, 0) == UNZ_OK)
|
if (unzGetCurrentFileInfo(
|
||||||
|
m_PackageUnzFile, &ufi, cBuffer, _countof(cBuffer), nullptr, 0, nullptr, 0) == UNZ_OK)
|
||||||
{
|
{
|
||||||
MultiByteToWideChar(CP_ACP, 0, cBuffer, strlen(cBuffer) + 1, buffer, MAX_PATH);
|
const uLong ZIP_UTF8_FLAG = 1 << 11;
|
||||||
|
const DWORD codePage = (ufi.flag & ZIP_UTF8_FLAG) ? CP_UTF8 : CP_ACP;
|
||||||
|
MultiByteToWideChar(codePage, 0, cBuffer, strlen(cBuffer) + 1, buffer, MAX_PATH);
|
||||||
while (WCHAR* pos = wcschr(buffer, L'/')) *pos = L'\\';
|
while (WCHAR* pos = wcschr(buffer, L'/')) *pos = L'\\';
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
#include "../Common/StringUtil.h"
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "DialogPackage.h"
|
#include "DialogPackage.h"
|
||||||
#include "DialogInstall.h"
|
#include "DialogInstall.h"
|
||||||
@ -37,7 +38,8 @@ DialogPackage::DialogPackage(HWND wnd) : Dialog(wnd),
|
|||||||
m_LoadLayout(false),
|
m_LoadLayout(false),
|
||||||
m_MergeSkins(false),
|
m_MergeSkins(false),
|
||||||
m_PackagerThread(),
|
m_PackagerThread(),
|
||||||
m_ZipFile()
|
m_ZipFile(),
|
||||||
|
m_AllowNonAsciiFilenames(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,12 +265,16 @@ bool DialogPackage::CreatePackage()
|
|||||||
WritePrivateProfileString(L"rmskin", L"MinimumRainmeter", m_MinimumRainmeter.c_str(), tempFile);
|
WritePrivateProfileString(L"rmskin", L"MinimumRainmeter", m_MinimumRainmeter.c_str(), tempFile);
|
||||||
WritePrivateProfileString(L"rmskin", L"MinimumWindows", m_MinimumWindows.c_str(), tempFile);
|
WritePrivateProfileString(L"rmskin", L"MinimumWindows", m_MinimumWindows.c_str(), tempFile);
|
||||||
|
|
||||||
|
// Only Skin Installer in Rainmeter 3.0.1 support UTF-8 filenames.
|
||||||
|
m_AllowNonAsciiFilenames = DialogInstall::CompareVersions(m_MinimumRainmeter, L"3.0.1") != -1;
|
||||||
|
|
||||||
// Create archive and add options file and header bitmap
|
// Create archive and add options file and header bitmap
|
||||||
m_ZipFile = zipOpen(ConvertToAscii(m_TargetFile.c_str()).c_str(), APPEND_STATUS_CREATE);
|
m_ZipFile = zipOpen(ConvertToAscii(m_TargetFile.c_str()).c_str(), APPEND_STATUS_CREATE);
|
||||||
|
|
||||||
auto cleanup = [&]()->bool
|
auto cleanup = [&]()->bool
|
||||||
{
|
{
|
||||||
zipClose(m_ZipFile, nullptr);
|
zipClose(m_ZipFile, nullptr);
|
||||||
|
DeleteFile(m_TargetFile.c_str());
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -379,17 +385,30 @@ unsigned __stdcall DialogPackage::PackagerThreadProc(void* pParam)
|
|||||||
|
|
||||||
bool DialogPackage::AddFileToPackage(const WCHAR* filePath, const WCHAR* zipPath)
|
bool DialogPackage::AddFileToPackage(const WCHAR* filePath, const WCHAR* zipPath)
|
||||||
{
|
{
|
||||||
std::string zipPathAscii = ConvertToAscii(zipPath);
|
std::string zipPathUTF8 = StringUtil::NarrowUTF8(zipPath);
|
||||||
for (int i = 0, isize = zipPathAscii.length(); i < isize; ++i)
|
for (int i = 0, isize = zipPathUTF8.length(); i < isize; ++i)
|
||||||
{
|
{
|
||||||
if (zipPathAscii[i] == '\\')
|
if ((zipPathUTF8[i] & 0x80) != 0)
|
||||||
{
|
{
|
||||||
zipPathAscii[i] = '/';
|
// UTF-8 lead bit is not zero so the string is non-ASCII.
|
||||||
|
if (!m_AllowNonAsciiFilenames)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int open = zipOpenNewFileInZip(m_ZipFile, zipPathAscii.c_str(), nullptr, nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
|
if (zipPathUTF8[i] == '\\')
|
||||||
if (open != ZIP_OK)
|
{
|
||||||
|
zipPathUTF8[i] = '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const uLong ZIP_UTF8_FLAG = 1 << 11;
|
||||||
|
zip_fileinfo fi = {0};
|
||||||
|
if (zipOpenNewFileInZip4(
|
||||||
|
m_ZipFile, zipPathUTF8.c_str(), &fi,
|
||||||
|
nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, Z_DEFAULT_COMPRESSION,
|
||||||
|
0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, NULL, 0, 0, ZIP_UTF8_FLAG) != ZIP_OK)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -121,6 +121,7 @@ private:
|
|||||||
|
|
||||||
HANDLE m_PackagerThread;
|
HANDLE m_PackagerThread;
|
||||||
zipFile m_ZipFile;
|
zipFile m_ZipFile;
|
||||||
|
bool m_AllowNonAsciiFilenames;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -122,6 +122,7 @@
|
|||||||
</Manifest>
|
</Manifest>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\Common\StringUtil.cpp" />
|
||||||
<ClCompile Include="..\Library\Dialog.cpp" />
|
<ClCompile Include="..\Library\Dialog.cpp" />
|
||||||
<ClCompile Include="Application.cpp" />
|
<ClCompile Include="Application.cpp" />
|
||||||
<ClCompile Include="DialogInstall.cpp" />
|
<ClCompile Include="DialogInstall.cpp" />
|
||||||
|
@ -19,6 +19,9 @@
|
|||||||
<Filter Include="zlib\minizip">
|
<Filter Include="zlib\minizip">
|
||||||
<UniqueIdentifier>{b726e25d-2977-424a-b45b-8ee60ce6bd49}</UniqueIdentifier>
|
<UniqueIdentifier>{b726e25d-2977-424a-b45b-8ee60ce6bd49}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="Common">
|
||||||
|
<UniqueIdentifier>{b69ece81-b900-41d8-9ccd-61476261c411}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Application.cpp">
|
<ClCompile Include="Application.cpp">
|
||||||
@ -81,6 +84,9 @@
|
|||||||
<ClCompile Include="DialogPackage.cpp">
|
<ClCompile Include="DialogPackage.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\Common\StringUtil.cpp">
|
||||||
|
<Filter>Common</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="resource.h">
|
<ClInclude Include="resource.h">
|
||||||
|
Loading…
Reference in New Issue
Block a user