Wrap fopen calls under Windows
The idea is that all filenames we deal with are encoded as UTF-8, but the Windows functions that take a char string interpret it using the ANSI codepage. So instead, we convert the UTF-8 string to a wchar string, and then use the wchar functions for proper extended character filename support.
This commit is contained in:
@@ -893,7 +893,7 @@ static void alc_initconfig(void)
|
||||
str = getenv("ALSOFT_LOGFILE");
|
||||
if(str && str[0])
|
||||
{
|
||||
FILE *logfile = fopen(str, "wt");
|
||||
FILE *logfile = al_fopen(str, "wt");
|
||||
if(logfile) LogFile = logfile;
|
||||
else ERR("Failed to open log file '%s'\n", str);
|
||||
}
|
||||
|
||||
+9
-9
@@ -32,13 +32,13 @@
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "alMain.h"
|
||||
|
||||
#ifdef _WIN32_IE
|
||||
#include <shlobj.h>
|
||||
#endif
|
||||
|
||||
#include "alMain.h"
|
||||
#include "compat.h"
|
||||
|
||||
|
||||
typedef struct ConfigEntry {
|
||||
char *key;
|
||||
@@ -304,7 +304,7 @@ void ReadALConfig(void)
|
||||
snprintf(buffer+p, sizeof(buffer)-p, "\\alsoft.ini");
|
||||
|
||||
TRACE("Loading config %s...\n", buffer);
|
||||
f = fopen(buffer, "rt");
|
||||
f = al_fopen(buffer, "rt");
|
||||
if(f)
|
||||
{
|
||||
LoadConfigFromFile(f);
|
||||
@@ -315,7 +315,7 @@ void ReadALConfig(void)
|
||||
str = "/etc/openal/alsoft.conf";
|
||||
|
||||
TRACE("Loading config %s...\n", str);
|
||||
f = fopen(str, "r");
|
||||
f = al_fopen(str, "r");
|
||||
if(f)
|
||||
{
|
||||
LoadConfigFromFile(f);
|
||||
@@ -346,7 +346,7 @@ void ReadALConfig(void)
|
||||
buffer[sizeof(buffer)-1] = 0;
|
||||
|
||||
TRACE("Loading config %s...\n", next);
|
||||
f = fopen(next, "r");
|
||||
f = al_fopen(next, "r");
|
||||
if(f)
|
||||
{
|
||||
LoadConfigFromFile(f);
|
||||
@@ -362,7 +362,7 @@ void ReadALConfig(void)
|
||||
snprintf(buffer, sizeof(buffer), "%s/.alsoftrc", str);
|
||||
|
||||
TRACE("Loading config %s...\n", buffer);
|
||||
f = fopen(buffer, "r");
|
||||
f = al_fopen(buffer, "r");
|
||||
if(f)
|
||||
{
|
||||
LoadConfigFromFile(f);
|
||||
@@ -381,7 +381,7 @@ void ReadALConfig(void)
|
||||
if(buffer[0] != 0)
|
||||
{
|
||||
TRACE("Loading config %s...\n", buffer);
|
||||
f = fopen(buffer, "r");
|
||||
f = al_fopen(buffer, "r");
|
||||
if(f)
|
||||
{
|
||||
LoadConfigFromFile(f);
|
||||
@@ -393,7 +393,7 @@ void ReadALConfig(void)
|
||||
if((str=getenv("ALSOFT_CONF")) != NULL && *str)
|
||||
{
|
||||
TRACE("Loading config %s...\n", str);
|
||||
f = fopen(str, "r");
|
||||
f = al_fopen(str, "r");
|
||||
if(f)
|
||||
{
|
||||
LoadConfigFromFile(f);
|
||||
|
||||
+1
-1
@@ -183,7 +183,7 @@ static ALCenum wave_open_playback(ALCdevice *device, const ALCchar *deviceName)
|
||||
|
||||
data = (wave_data*)calloc(1, sizeof(wave_data));
|
||||
|
||||
data->f = fopen(fname, "wb");
|
||||
data->f = al_fopen(fname, "wb");
|
||||
if(!data->f)
|
||||
{
|
||||
free(data);
|
||||
|
||||
@@ -23,6 +23,9 @@ inline int alsched_yield(void)
|
||||
|
||||
WCHAR *strdupW(const WCHAR *str);
|
||||
|
||||
/* Opens a file with standard I/O. The filename is expected to be UTF-8. */
|
||||
FILE *al_fopen(const char *fname, const char *mode);
|
||||
|
||||
#define HAVE_DYNLOAD 1
|
||||
|
||||
#else
|
||||
@@ -50,6 +53,8 @@ void Sleep(ALuint t);
|
||||
|
||||
#define alsched_yield sched_yield
|
||||
|
||||
#define al_fopen(_n, _m) fopen((_n), (_m))
|
||||
|
||||
#if defined(HAVE_DLFCN_H) && !defined(IN_IDE_PARSER)
|
||||
#define HAVE_DYNLOAD 1
|
||||
#endif
|
||||
|
||||
+36
-5
@@ -375,6 +375,37 @@ WCHAR *strdupW(const WCHAR *str)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
FILE *al_fopen(const char *fname, const char *mode)
|
||||
{
|
||||
WCHAR *wname=NULL, *wmode=NULL;
|
||||
FILE *file = NULL;
|
||||
int len;
|
||||
|
||||
if((len=MultiByteToWideChar(CP_UTF8, 0, fname, -1, NULL, 0)) > 0)
|
||||
{
|
||||
wname = calloc(sizeof(WCHAR), len);
|
||||
MultiByteToWideChar(CP_UTF8, 0, fname, -1, wname, len);
|
||||
}
|
||||
if((len=MultiByteToWideChar(CP_UTF8, 0, mode, -1, NULL, 0)) > 0)
|
||||
{
|
||||
wmode = calloc(sizeof(WCHAR), len);
|
||||
MultiByteToWideChar(CP_UTF8, 0, mode, -1, wmode, len);
|
||||
}
|
||||
|
||||
if(!wname)
|
||||
ERR("Failed to convert UTF-8 filename: \"%s\"\n", fname);
|
||||
else if(!wmode)
|
||||
ERR("Failed to convert UTF-8 mode: \"%s\"\n", mode);
|
||||
else
|
||||
file = _wfopen(wname, wmode);
|
||||
|
||||
free(wname);
|
||||
free(wmode);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <pthread.h>
|
||||
@@ -526,7 +557,7 @@ FILE *OpenDataFile(const char *fname, const char *subdir)
|
||||
/* If the path is absolute, open it directly. */
|
||||
if(fname[0] != '\0' && fname[1] == ':' && (fname[2] == '\\' || fname[2] == '/'))
|
||||
{
|
||||
if((f=fopen(fname, "rb")) != NULL)
|
||||
if((f=al_fopen(fname, "rb")) != NULL)
|
||||
{
|
||||
TRACE("Opened %s\n", fname);
|
||||
return f;
|
||||
@@ -554,7 +585,7 @@ FILE *OpenDataFile(const char *fname, const char *subdir)
|
||||
buffer[len] = '\\';
|
||||
}
|
||||
|
||||
if((f=fopen(buffer, "rb")) != NULL)
|
||||
if((f=al_fopen(buffer, "rb")) != NULL)
|
||||
{
|
||||
TRACE("Opened %s\n", buffer);
|
||||
return f;
|
||||
@@ -566,7 +597,7 @@ FILE *OpenDataFile(const char *fname, const char *subdir)
|
||||
|
||||
if(fname[0] == '/')
|
||||
{
|
||||
if((f=fopen(fname, "rb")) != NULL)
|
||||
if((f=al_fopen(fname, "rb")) != NULL)
|
||||
{
|
||||
TRACE("Opened %s\n", fname);
|
||||
return f;
|
||||
@@ -581,7 +612,7 @@ FILE *OpenDataFile(const char *fname, const char *subdir)
|
||||
snprintf(buffer, sizeof(buffer), "%s/.local/share/%s/%s", str, subdir, fname);
|
||||
if(buffer[0])
|
||||
{
|
||||
if((f=fopen(buffer, "rb")) != NULL)
|
||||
if((f=al_fopen(buffer, "rb")) != NULL)
|
||||
{
|
||||
TRACE("Opened %s\n", buffer);
|
||||
return f;
|
||||
@@ -612,7 +643,7 @@ FILE *OpenDataFile(const char *fname, const char *subdir)
|
||||
buffer[len] = '\0';
|
||||
snprintf(buffer+len, sizeof(buffer)-len, "/%s/%s", subdir, fname);
|
||||
|
||||
if((f=fopen(buffer, "rb")) != NULL)
|
||||
if((f=al_fopen(buffer, "rb")) != NULL)
|
||||
{
|
||||
TRACE("Opened %s\n", buffer);
|
||||
return f;
|
||||
|
||||
Reference in New Issue
Block a user