Skip to content

Commit 792e478

Browse files
committed
Fix file name encoding issues with VST on Windows
Fix plugin loading and setting loading/saving
1 parent e9f2b57 commit 792e478

File tree

2 files changed

+84
-11
lines changed

2 files changed

+84
-11
lines changed

Diff for: include/IoHelper.h

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* IoHelper.h - helper functions for file I/O
3+
*
4+
* Copyright (c) 2018 Hyunjin Song <tteu.ingog/at/gmail.com>
5+
*
6+
* This file is part of LMMS - https://lmms.io
7+
*
8+
* This program is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU General Public
10+
* License as published by the Free Software Foundation; either
11+
* version 2 of the License, or (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+
* General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU General Public
19+
* License along with this program (see COPYING); if not, write to the
20+
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21+
* Boston, MA 02110-1301 USA.
22+
*
23+
*/
24+
25+
26+
#include "lmmsconfig.h"
27+
28+
#include <cstdio>
29+
30+
31+
#ifdef _WIN32
32+
#include <windows.h>
33+
34+
std::wstring toWString(const std::string& s)
35+
{
36+
std::wstring ret;
37+
int len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, s.data(),
38+
s.length(), nullptr, 0);
39+
if (len == 0)
40+
{
41+
return ret;
42+
}
43+
ret.resize(len);
44+
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s.length(), &ret[0], len);
45+
return ret;
46+
}
47+
#endif
48+
49+
#ifdef LMMS_BUILD_WIN32
50+
#include <io.h>
51+
#define F_OPEN_UTF8(a, b) _wfopen(toWString(a).data(), L##b)
52+
#else
53+
#ifdef LMMS_HAVE_UNISTD_H
54+
#include <unistd.h>
55+
#endif
56+
#define F_OPEN_UTF8(a, b) fopen((a).data(), b)
57+
#endif
58+
59+
int fileToDescriptor(FILE* f, bool closeFile = true)
60+
{
61+
int fh;
62+
if (f == NULL) {return -1;}
63+
64+
#ifdef LMMS_BUILD_WIN32
65+
fh = _dup(_fileno(f));
66+
#else
67+
fh = dup(fileno(f));
68+
#endif
69+
70+
if (closeFile) {fclose(f);}
71+
return fh;
72+
}

Diff for: plugins/vst_base/RemoteVstPlugin.cpp

+12-11
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ struct ERect
8888
#include "lmms_basics.h"
8989
#include "Midi.h"
9090
#include "communication.h"
91+
#include "IoHelper.h"
9192

9293
#include "VstSyncData.h"
9394

@@ -678,9 +679,9 @@ void RemoteVstPlugin::init( const std::string & _plugin_file )
678679

679680

680681

681-
static void close_check( int fd )
682+
static void close_check( FILE* fp )
682683
{
683-
if( close( fd ) )
684+
if( fclose( fp ) )
684685
{
685686
perror( "close" );
686687
}
@@ -790,7 +791,7 @@ void RemoteVstPlugin::destroyEditor()
790791

791792
bool RemoteVstPlugin::load( const std::string & _plugin_file )
792793
{
793-
if( ( m_libInst = LoadLibrary( _plugin_file.c_str() ) ) == NULL )
794+
if( ( m_libInst = LoadLibraryW( toWString(_plugin_file).c_str() ) ) == NULL )
794795
{
795796
// give VstPlugin class a chance to start 32 bit version of RemoteVstPlugin
796797
if( GetLastError() == ERROR_BAD_EXE_FORMAT )
@@ -1072,13 +1073,13 @@ void RemoteVstPlugin::saveChunkToFile( const std::string & _file )
10721073
const int len = pluginDispatch( 23, 0, 0, &chunk );
10731074
if( len > 0 )
10741075
{
1075-
int fd = open( _file.c_str(), O_WRONLY | O_BINARY );
1076-
if ( ::write( fd, chunk, len ) != len )
1076+
FILE* fp = F_OPEN_UTF8( _file, "wb" );
1077+
if ( fwrite( chunk, len, 1, fp ) != len )
10771078
{
10781079
fprintf( stderr,
10791080
"Error saving chunk to file.\n" );
10801081
}
1081-
close_check( fd );
1082+
close_check( fp );
10821083
}
10831084
}
10841085
}
@@ -1237,7 +1238,7 @@ void RemoteVstPlugin::savePreset( const std::string & _file )
12371238
if (!isPreset &&!chunky) uIntToFile = (unsigned int) m_plugin->numPrograms;
12381239
pBank->numPrograms = endian_swap( uIntToFile );
12391240

1240-
FILE * stream = fopen( _file.c_str(), "w" );
1241+
FILE * stream = F_OPEN_UTF8( _file, "w" );
12411242
fwrite ( pBank, 1, 28, stream );
12421243
fwrite ( progName, 1, isPreset ? 28 : 128, stream );
12431244
if ( chunky ) {
@@ -1289,7 +1290,7 @@ void RemoteVstPlugin::loadPresetFile( const std::string & _file )
12891290
unsigned int * pLen = new unsigned int[ 1 ];
12901291
unsigned int len = 0;
12911292
sBank * pBank = (sBank*) new char[ sizeof( sBank ) ];
1292-
FILE * stream = fopen( _file.c_str(), "r" );
1293+
FILE * stream = F_OPEN_UTF8( _file, "r" );
12931294
if ( fread ( pBank, 1, 56, stream ) != 56 )
12941295
{
12951296
fprintf( stderr, "Error loading preset file.\n" );
@@ -1390,12 +1391,12 @@ void RemoteVstPlugin::loadChunkFromFile( const std::string & _file, int _len )
13901391
{
13911392
char * chunk = new char[_len];
13921393

1393-
const int fd = open( _file.c_str(), O_RDONLY | O_BINARY );
1394-
if ( ::read( fd, chunk, _len ) != _len )
1394+
FILE* fp = F_OPEN_UTF8( _file, "rb" );
1395+
if ( fread( chunk, 1, _len, fp ) != _len )
13951396
{
13961397
fprintf( stderr, "Error loading chunk from file.\n" );
13971398
}
1398-
close_check( fd );
1399+
close_check( fp );
13991400

14001401
pluginDispatch( effSetChunk, 0, _len, chunk );
14011402

0 commit comments

Comments
 (0)