This fixes an issue while the path includes non-ASCII characters.
From: Jactry Zeng jzeng@codeweavers.com
--- dlls/msi/media.c | 8 ++++++-- dlls/msi/msipriv.h | 8 ++++---- 2 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/dlls/msi/media.c b/dlls/msi/media.c index 50673f99cae..5b33594f2d8 100644 --- a/dlls/msi/media.c +++ b/dlls/msi/media.c @@ -109,6 +109,8 @@ static INT_PTR CDECL cabinet_open(char *pszFile, int oflag, int pmode) DWORD dwAccess = 0; DWORD dwShareMode = 0; DWORD dwCreateDisposition = OPEN_EXISTING; + HANDLE handle; + WCHAR *path;
switch (oflag & _O_ACCMODE) { @@ -131,8 +133,10 @@ static INT_PTR CDECL cabinet_open(char *pszFile, int oflag, int pmode) else if (oflag & _O_CREAT) dwCreateDisposition = CREATE_ALWAYS;
- return (INT_PTR)CreateFileA(pszFile, dwAccess, dwShareMode, NULL, - dwCreateDisposition, 0, NULL); + path = strdupAtoW(pszFile); + handle = CreateFileW(path, dwAccess, dwShareMode, NULL, dwCreateDisposition, 0, NULL); + free(path); + return (INT_PTR)handle; }
static UINT CDECL cabinet_read(INT_PTR hf, void *pv, UINT cb) diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index 89495b5a6a5..c3c66b6e610 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -1148,10 +1148,10 @@ static inline char *strdupWtoA( LPCWSTR str ) DWORD len;
if (!str) return ret; - len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL); + len = WideCharToMultiByte( CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL); ret = malloc( len ); if (ret) - WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL ); + WideCharToMultiByte( CP_UTF8, 0, str, -1, ret, len, NULL, NULL ); return ret; }
@@ -1161,10 +1161,10 @@ static inline LPWSTR strdupAtoW( LPCSTR str ) DWORD len;
if (!str) return ret; - len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 ); + len = MultiByteToWideChar( CP_UTF8, 0, str, -1, NULL, 0 ); ret = malloc( len * sizeof(WCHAR) ); if (ret) - MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len ); + MultiByteToWideChar( CP_UTF8, 0, str, -1, ret, len ); return ret; }
Do you have an installer that shows this? This could use a test case.
So it's winemono-support.msi that fails when the installer path includes non-ascii characters. The problem is that the Cabinet API doesn't support wide character strings. We can pass a UTF-8 string instead like you do since the cabinet filename is handled by a callback that we also implement. We can't change strdupAtoW() and strdupWtoA() to assume UTF-8 strings however, because these helpers are used in functions that expect ANSI strings. It would need new helpers like strdupUtoW() and strdupWtoU().
Jactry, is it clear what needs to be done?
On Fri Sep 8 16:12:33 2023 +0000, Hans Leidekker wrote:
Jactry, is it clear what needs to be done?
Hi Hans,
Sorry for the delay! I just didn't find time to revisit this. If I understand it correctly, I will need a new helper strdupUtoW(), and use it from cabinet_open() instead of modifying and using strdupAtoW(), right?
On Fri Sep 8 16:12:33 2023 +0000, Jactry Zeng wrote:
Hi Hans, Sorry for the delay! I just didn't find time to revisit this. If I understand it correctly, I will need a new helper strdupUtoW(), and use it from cabinet_open() instead of modifying and using strdupAtoW(), right?
Right, strdupUtoW() in cabinet_open() and strdupWtoU() in extract_cabinet() for the cabinet name and path.