3 cli/win32_unicode_support.c | 197 ++++++++++++++++++++++++++++++++++++++++++++
4 cli/win32_unicode_support.h | 49 +++++++++++
5 cli/wvunpack.c | 71 +++++++++++++---
6 src/open_utils.c | 5 +-
7 6 files changed, 331 insertions(+), 18 deletions(-)
9 diff --git a/.gitignore b/.gitignore
10 index eb3a2f7..b09320e 100644
21 diff --git a/cli/utils.c b/cli/utils.c
22 index 8ead3df..9925a8c 100644
29 +#include "win32_unicode_support.h"
32 #define fileno _fileno
33 @@ -81,7 +82,7 @@ int copy_timestamp(const char *src_filename, const char *dst_filename)
34 if (strcmp(src_filename, "-") == 0 || strcmp(dst_filename, "-") == 0)
37 - if (stat(src_filename, &fileinfo))
38 + if (stat_utf8(src_filename, &fileinfo))
39 return FALSE; /* stat failed */
41 times[0].tv_sec = fileinfo.st_atime;
42 @@ -186,7 +187,7 @@ char *filespec_path (char *filespec)
45 /* test if the file is a directory */
46 - if (stat(globs.gl_pathv[0], &fstats) == 0 && (fstats.st_mode & S_IFDIR)) {
47 + if (stat_utf8(globs.gl_pathv[0], &fstats) == 0 && (fstats.st_mode & S_IFDIR)) {
49 strcat (filespec, globs.gl_pathv[0]);
51 @@ -368,6 +369,7 @@ char yna (void)
52 fprintf (stderr, "%c", 7);
59 @@ -446,6 +448,7 @@ void error_line (char *error, ...)
60 vsprintf (error_msg + 1, error, argptr);
62 fputs (error_msg, stderr);
66 if (debug_logging_mode) {
67 @@ -454,7 +457,7 @@ void error_line (char *error, ...)
69 if (get_app_path (file_path)) {
70 strcat (file_path, "\\WavPack\\wavpack.log");
71 - error_log = fopen (file_path, "a+");
72 + error_log = fopen_utf8 (file_path, "a+");
75 get_app_path (file_path);
76 @@ -462,13 +465,13 @@ void error_line (char *error, ...)
78 if (CreateDirectory (file_path, NULL)) {
79 strcat (file_path, "\\wavpack.log");
80 - error_log = fopen (file_path, "a+");
81 + error_log = fopen_utf8 (file_path, "a+");
87 - error_log = fopen ("c:\\wavpack.log", "a+");
88 + error_log = fopen_utf8 ("c:\\wavpack.log", "a+");
91 fputs (error_msg + 1, error_log);
92 @@ -490,6 +493,7 @@ void error_line (char *error, ...)
93 vsprintf (error_msg + 1, error, argptr);
95 fputs (error_msg, stderr);
100 @@ -508,10 +512,11 @@ void debug_line (char *error, ...)
101 vsprintf (error_msg + 1, error, argptr);
103 fputs (error_msg, stderr);
107 if (debug_logging_mode) {
108 - FILE *error_log = fopen ("c:\\wavpack.log", "a+");
109 + FILE *error_log = fopen_utf8 ("c:\\wavpack.log", "a+");
112 fputs (error_msg + 1, error_log);
113 @@ -589,6 +594,8 @@ void finish_line (void)
116 fputc ('\n', stderr);
121 //////////////////////////////////////////////////////////////////////////////
122 @@ -599,6 +606,7 @@ void finish_line (void)
123 void finish_line (void)
125 fprintf (stderr, " \n");
129 //////////////////////////////////////////////////////////////////////////////
130 @@ -778,6 +786,7 @@ void DoSetConsoleTitle (char *text)
131 void DoSetConsoleTitle (char *text)
133 fprintf (stderr, "\033]0;%s\007", text);
138 diff --git a/cli/win32_unicode_support.c b/cli/win32_unicode_support.c
140 index 0000000..513cebc
142 +++ b/cli/win32_unicode_support.c
144 +/* Copyright (c) 2004-2012 LoRd_MuldeR <mulder2@gmx.de>
145 + File: unicode_support.c
147 + This file was originally part of a patch included with LameXP,
148 + released under the same license as the original audio tools.
150 + Redistribution and use in source and binary forms, with or without
151 + modification, are permitted provided that the following conditions
154 + - Redistributions of source code must retain the above copyright
155 + notice, this list of conditions and the following disclaimer.
157 + - Redistributions in binary form must reproduce the above copyright
158 + notice, this list of conditions and the following disclaimer in the
159 + documentation and/or other materials provided with the distribution.
161 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
162 + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
163 + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
164 + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
165 + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
166 + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
167 + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
168 + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
169 + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
170 + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
171 + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
173 +#if defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64
175 +#include "win32_unicode_support.h"
177 +#include <windows.h>
180 +static UINT g_old_output_cp = ((UINT)-1);
182 +char *utf16_to_utf8(const wchar_t *input)
185 + int BuffSize = 0, Result = 0;
187 + BuffSize = WideCharToMultiByte(CP_UTF8, 0, input, -1, NULL, 0, NULL, NULL);
188 + Buffer = (char*) malloc(sizeof(char) * BuffSize);
191 + Result = WideCharToMultiByte(CP_UTF8, 0, input, -1, Buffer, BuffSize, NULL, NULL);
194 + return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL;
197 +char *utf16_to_ansi(const wchar_t *input)
200 + int BuffSize = 0, Result = 0;
202 + BuffSize = WideCharToMultiByte(CP_ACP, 0, input, -1, NULL, 0, NULL, NULL);
203 + Buffer = (char*) malloc(sizeof(char) * BuffSize);
206 + Result = WideCharToMultiByte(CP_ACP, 0, input, -1, Buffer, BuffSize, NULL, NULL);
209 + return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL;
212 +wchar_t *utf8_to_utf16(const char *input)
215 + int BuffSize = 0, Result = 0;
217 + BuffSize = MultiByteToWideChar(CP_UTF8, 0, input, -1, NULL, 0);
218 + Buffer = (wchar_t*) malloc(sizeof(wchar_t) * BuffSize);
221 + Result = MultiByteToWideChar(CP_UTF8, 0, input, -1, Buffer, BuffSize);
224 + return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL;
227 +void init_commandline_arguments_utf8(int *argc, char ***argv)
232 + szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
234 + if(NULL == szArglist)
236 + fprintf(stderr, "\nFATAL: CommandLineToArgvW failed\n\n");
240 + *argv = (char**) malloc(sizeof(char*) * nArgs);
245 + fprintf(stderr, "\nFATAL: Malloc failed\n\n");
249 + for(i = 0; i < nArgs; i++)
251 + (*argv)[i] = utf16_to_utf8(szArglist[i]);
252 + if(NULL == (*argv)[i])
254 + fprintf(stderr, "\nFATAL: utf16_to_utf8 failed\n\n");
259 + LocalFree(szArglist);
262 +void free_commandline_arguments_utf8(int *argc, char ***argv)
268 + for(i = 0; i < *argc; i++)
270 + if((*argv)[i] != NULL)
281 +FILE *fopen_utf8(const char *filename_utf8, const char *mode_utf8)
284 + wchar_t *filename_utf16 = utf8_to_utf16(filename_utf8);
285 + wchar_t *mode_utf16 = utf8_to_utf16(mode_utf8);
287 + if(filename_utf16 && mode_utf16)
289 + ret = _wfopen(filename_utf16, mode_utf16);
292 + if(filename_utf16) free(filename_utf16);
293 + if(mode_utf16) free(mode_utf16);
298 +int stat_utf8(const char *path_utf8, struct _stat *buf)
302 + wchar_t *path_utf16 = utf8_to_utf16(path_utf8);
305 + ret = _wstat(path_utf16, buf);
312 +int unlink_utf8(const char *path_utf8)
316 + wchar_t *path_utf16 = utf8_to_utf16(path_utf8);
319 + ret = _wunlink(path_utf16);
326 +void init_console_utf8(void)
328 + g_old_output_cp = GetConsoleOutputCP();
329 + SetConsoleOutputCP(CP_UTF8);
332 +void uninit_console_utf8(void)
334 + if(g_old_output_cp != ((UINT)-1))
336 + SetConsoleOutputCP(g_old_output_cp);
341 diff --git a/cli/win32_unicode_support.h b/cli/win32_unicode_support.h
343 index 0000000..40c2e33
345 +++ b/cli/win32_unicode_support.h
347 +/* Copyright (c) 2004-2012 LoRd_MuldeR <mulder2@gmx.de>
348 + File: unicode_support.h
350 + This file was originally part of a patch included with LameXP,
351 + released under the same license as the original audio tools.
353 + Redistribution and use in source and binary forms, with or without
354 + modification, are permitted provided that the following conditions
357 + - Redistributions of source code must retain the above copyright
358 + notice, this list of conditions and the following disclaimer.
360 + - Redistributions in binary form must reproduce the above copyright
361 + notice, this list of conditions and the following disclaimer in the
362 + documentation and/or other materials provided with the distribution.
364 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
365 + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
366 + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
367 + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
368 + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
369 + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
370 + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
371 + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
372 + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
373 + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
374 + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
376 +#ifndef UNICODE_SUPPORT_H_INCLUDED
377 +#define UNICODE_SUPPORT_H_INCLUDED
380 +#include <sys/stat.h>
382 +#define WIN_UNICODE 1
384 +char *utf16_to_utf8(const wchar_t *input);
385 +char *utf16_to_ansi(const wchar_t *input);
386 +wchar_t *utf8_to_utf16(const char *input);
387 +void init_commandline_arguments_utf8(int *argc, char ***argv);
388 +void free_commandline_arguments_utf8(int *argc, char ***argv);
389 +FILE *fopen_utf8(const char *filename_utf8, const char *mode_utf8);
390 +int stat_utf8(const char *path_utf8, struct _stat *buf);
391 +int unlink_utf8(const char *path_utf8);
392 +void init_console_utf8(void);
393 +void uninit_console_utf8(void);
396 diff --git a/cli/wvunpack.c b/cli/wvunpack.c
397 index e12b5c3..255a6a5 100644
404 +#include "win32_unicode_support.h"
407 #define strdup(x) _strdup(x)
408 @@ -159,7 +160,7 @@ static void display_progress (double file_progress);
409 // The "main" function for the command-line WavPack decompressor. //
410 //////////////////////////////////////////////////////////////////////////////
412 -int main (argc, argv) int argc; char **argv;
413 +static int wvunpack_main (argc, argv) int argc; char **argv;
415 #ifdef __EMX__ /* OS/2 */
416 _wildcard (&argc, &argv);
417 @@ -196,7 +197,7 @@ int main (argc, argv) int argc; char **argv;
421 - set_console_title = 1; // on Windows, we default to messing with the console title
422 + set_console_title = 0; // on Windows, we default to messing with the console title
423 #endif // on Linux, this is considered uncool to do by default
425 // loop through command-line arguments
426 @@ -450,9 +451,15 @@ int main (argc, argv) int argc; char **argv;
429 if (strcmp (WavpackGetLibraryVersionString (), PACKAGE_VERSION))
431 fprintf (stderr, version_warning, WavpackGetLibraryVersionString (), PACKAGE_VERSION);
434 else if (!quiet_mode && !error_count)
436 fprintf (stderr, sign_on, VERSION_OS, WavpackGetLibraryVersionString ());
441 printf ("%s", usage);
442 @@ -473,7 +480,7 @@ int main (argc, argv) int argc; char **argv;
443 // frontends, but could be used for other purposes.
445 if (*infilename == '@') {
446 - FILE *list = fopen (infilename+1, "rt");
447 + FILE *list = fopen_utf8 (infilename+1, "rt");
450 for (di = file_index; di < num_files - 1; di++)
451 @@ -517,7 +524,7 @@ int main (argc, argv) int argc; char **argv;
454 else if (filespec_wild (infilename)) {
455 - FILE *list = fopen (infilename+1, "rt");
456 + FILE *list = fopen_utf8 (infilename+1, "rt");
460 @@ -556,7 +563,7 @@ int main (argc, argv) int argc; char **argv;
461 // be passed on the command-line, but could be used for other purposes.
463 if (outfilename && outfilename [0] == '@') {
464 - FILE *list = fopen (outfilename+1, "rt");
465 + FILE *list = fopen_utf8 (outfilename+1, "rt");
469 @@ -629,7 +636,10 @@ int main (argc, argv) int argc; char **argv;
470 strcat (outfilename, raw_decode ? ".raw" : ".wav");
472 if (num_files > 1 && !quiet_mode)
474 fprintf (stderr, "\n%s:\n", matches [file_index]);
478 result = unpack_file (matches [file_index], verify_only ? NULL : outfilename);
480 @@ -653,9 +663,15 @@ int main (argc, argv) int argc; char **argv;
485 fprintf (stderr, "\n **** warning: errors occurred in %d of %d files! ****\n", error_count, num_files);
488 else if (!quiet_mode)
490 fprintf (stderr, "\n **** %d files successfully processed ****\n", num_files);
496 @@ -742,7 +758,7 @@ static FILE *open_output_file (char *filename, char **tempfilename)
500 - testfile = fopen (filename, "rb");
501 + testfile = fopen_utf8 (filename, "rb");
504 size_t res = fread (&dummy, 1, 1, testfile);
505 @@ -754,6 +770,7 @@ static FILE *open_output_file (char *filename, char **tempfilename)
507 if (!overwrite_all) {
508 fprintf (stderr, "overwrite %s (yes/no/all)? ", FN_FIT (filename));
511 if (set_console_title)
512 DoSetConsoleTitle ("overwrite?");
513 @@ -787,7 +804,7 @@ static FILE *open_output_file (char *filename, char **tempfilename)
514 strcat (*tempfilename, ".tmp");
517 - testfile = fopen (*tempfilename, "rb");
518 + testfile = fopen_utf8 (*tempfilename, "rb");
522 @@ -801,7 +818,7 @@ static FILE *open_output_file (char *filename, char **tempfilename)
526 - retval = fopen (*tempfilename ? *tempfilename : filename, "w+b");
527 + retval = fopen_utf8 (*tempfilename ? *tempfilename : filename, "w+b");
530 error_line ("can't create file %s!", *tempfilename ? *tempfilename : filename);
531 @@ -960,11 +977,17 @@ static int unpack_file (char *infilename, char *outfilename)
533 else if (*outfilename == '-') {
536 fprintf (stderr, "unpacking %s%s to stdout,", *infilename == '-' ?
537 "stdin" : FN_FIT (infilename), wvc_mode ? " (+.wvc)" : "");
541 else if (!quiet_mode)
543 fprintf (stderr, "restoring %s,", FN_FIT (outfilename));
548 output_buffer_size = outbuf_k * 1024;
549 @@ -983,8 +1006,11 @@ static int unpack_file (char *infilename, char *outfilename)
554 fprintf (stderr, "verifying %s%s,", *infilename == '-' ? "stdin" :
555 FN_FIT (infilename), wvc_mode ? " (+.wvc)" : "");
561 @@ -1071,6 +1097,7 @@ static int unpack_file (char *infilename, char *outfilename)
563 fprintf (stderr, "\n");
566 DoTruncateFile (outfile);
569 @@ -1085,8 +1112,11 @@ static int unpack_file (char *infilename, char *outfilename)
570 progress = floor (progress * 100.0 + 0.5);
574 fprintf (stderr, "%s%3d%% done...",
575 nobs ? " " : "\b\b\b\b\b\b\b\b\b\b\b\b", (int) progress);
581 @@ -1364,9 +1394,10 @@ static int do_tag_extractions (WavpackContext *wpc, char *outfilename)
583 strcpy (filespec_name (full_filename), tag_filename);
585 - if (!overwrite_all && (outfile = fopen (full_filename, "r")) != NULL) {
586 + if (!overwrite_all && (outfile = fopen_utf8 (full_filename, "r")) != NULL) {
587 DoCloseHandle (outfile);
588 fprintf (stderr, "overwrite %s (yes/no/all)? ", FN_FIT (full_filename));
591 if (set_console_title)
592 DoSetConsoleTitle ("overwrite?");
593 @@ -1385,7 +1416,7 @@ static int do_tag_extractions (WavpackContext *wpc, char *outfilename)
594 // open output file for writing
596 if (*full_filename) {
597 - if ((outfile = fopen (full_filename, "w")) == NULL) {
598 + if ((outfile = fopen_utf8 (full_filename, "w")) == NULL) {
599 error_line ("can't create file %s!", FN_FIT (full_filename));
602 @@ -2074,3 +2105,23 @@ void display_progress (double file_progress)
603 DoSetConsoleTitle (title);
607 +//////////////////////////////////////////////////////////////////////////////
609 +//////////////////////////////////////////////////////////////////////////////
611 +int main(int argc, char **argv)
613 + int ret = -1, argc_utf8 = -1;
614 + char **argv_utf8 = NULL;
616 + init_console_utf8();
617 + init_commandline_arguments_utf8(&argc_utf8, &argv_utf8);
619 + ret = wvunpack_main(argc_utf8, argv_utf8);
621 + free_commandline_arguments_utf8(&argc_utf8, &argv_utf8);
622 + uninit_console_utf8();
626 diff --git a/src/open_utils.c b/src/open_utils.c
627 index a8c7baa..a77f90f 100644
628 --- a/src/open_utils.c
629 +++ b/src/open_utils.c
633 #include "wavpack_local.h"
634 +#include "../cli/win32_unicode_support.h"
636 // This code provides an interface between the reader callback mechanism that
637 // WavPack uses internally and the standard fstream C library. This allows an
638 @@ -137,7 +138,7 @@ WavpackContext *WavpackOpenFileInput (const char *infilename, char *error, int f
639 setmode (fileno (stdin), O_BINARY);
642 - else if ((wv_id = fopen (infilename, file_mode)) == NULL) {
643 + else if ((wv_id = fopen_utf8 (infilename, file_mode)) == NULL) {
644 if (error) strcpy (error, (flags & OPEN_EDIT_TAGS) ? "can't open file for editing" : "can't open file");
647 @@ -147,7 +148,7 @@ WavpackContext *WavpackOpenFileInput (const char *infilename, char *error, int f
649 strcpy (in2filename, infilename);
650 strcat (in2filename, "c");
651 - wvc_id = fopen (in2filename, "rb");
652 + wvc_id = fopen_utf8 (in2filename, "rb");