aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/helpers.c
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2014-03-28 00:37:42 -0700
committerChris Robinson <[email protected]>2014-03-28 00:37:42 -0700
commit20886059fd88724f724da8601a82e04fc3f03a53 (patch)
tree0f8c147ad311226ea9983d73e9ca18faade84e8f /Alc/helpers.c
parent18620ab5e00fb4cba97f3aa2bfbc677dfe8376ef (diff)
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.
Diffstat (limited to 'Alc/helpers.c')
-rw-r--r--Alc/helpers.c41
1 files changed, 36 insertions, 5 deletions
diff --git a/Alc/helpers.c b/Alc/helpers.c
index 59eb359e..1246e92b 100644
--- a/Alc/helpers.c
+++ b/Alc/helpers.c
@@ -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;