Hi Philip, I submitted the OCA, just check the inbox of the OCA mail.
Here's the patch, generated by hg export -g. If you think the thing you need isn't this, just tell me the exactly way to generate it. # HG changeset patch # User "CharlieJiang <cqjj...@126.com>" # Date 1501568294 -28800 # Tue Aug 01 14:18:14 2017 +0800 # Node ID 201964735a55e0b70e064cc24fbf9c85fbb55346 # Parent 2425838cfb5e63bf798e383492890c25170b91d1 8177951: Charset problem when the name of the sound device contains Chinese character diff --git a/make/lib/SoundLibraries.gmk b/make/lib/SoundLibraries.gmk --- a/make/lib/SoundLibraries.gmk +++ b/make/lib/SoundLibraries.gmk @@ -61,6 +61,7 @@ -DUSE_PLATFORM_MIDI_IN=TRUE \ -DUSE_PORTS=TRUE LIBJSOUND_SRC_FILES += \ + PLATFORM_API_WinOS_Charset_Util.cpp \ PLATFORM_API_WinOS_MidiIn.cpp \ PLATFORM_API_WinOS_MidiOut.c \ PLATFORM_API_WinOS_Util.c \ @@ -190,6 +191,7 @@ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ SRC := $(LIBJSOUND_SRC_DIRS), \ INCLUDE_FILES := Utilities.c $(LIBJSOUND_DAUDIOFILES) \ + PLATFORM_API_WinOS_Charset_Util.cpp \ PLATFORM_API_WinOS_DirectSound.cpp, \ OPTIMIZATION := LOW, \ CFLAGS := $(CFLAGS_JDKLIB) \ diff --git a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp new file mode 100644 --- /dev/null +++ b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "PLATFORM_API_WinOS_Charset_Util.h" + +#include <cstring> + +#ifdef __cplusplus +extern "C" { +#endif + +LPSTR UnicodeToUTF8(const LPCWSTR lpUnicodeStr) +{ + DWORD dwUTF8Len = WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, nullptr, 0, nullptr, nullptr); + LPSTR lpUTF8Str = new CHAR[dwUTF8Len]; + memset(lpUTF8Str, 0, sizeof(CHAR) * (dwUTF8Len)); + WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, lpUTF8Str, dwUTF8Len, nullptr, nullptr); + return lpUTF8Str; +} + +void UnicodeToUTF8AndCopy(LPSTR dest, LPCWSTR src, SIZE_T maxLength) { + LPSTR utf8EncodedName = UnicodeToUTF8(src); + strncpy(dest, utf8EncodedName, maxLength - 1); + delete[] utf8EncodedName; + dest[maxLength - 1] = '\0'; +} + +#ifdef __cplusplus +} +#endif + \ No newline at end of file diff --git a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.h b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.h new file mode 100644 --- /dev/null +++ b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#ifndef PLATFORM_API_WINOS_CHARSET_UTILS_H +#define PLATFORM_API_WINOS_CHARSET_UTILS_H + +#include <windows.h> + +#ifdef __cplusplus +extern "C" { +#endif + +LPSTR _cdecl UnicodeToUTF8(const LPCWSTR lpAnsiStr); + +void _cdecl UnicodeToUTF8AndCopy(LPSTR dest, LPCWSTR src, SIZE_T maxLength); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp --- a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp +++ b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp @@ -52,6 +52,9 @@ } #endif +/* include to prevent charset problem */ +#include "PLATFORM_API_WinOS_Charset_Util.h" + #ifdef USE_DEBUG_SILENCING #define DEBUG_SILENCING0(p) TRACE0(p) #define DEBUG_SILENCING1(p1,p2) TRACE1(p1,p2) @@ -227,13 +230,13 @@ } BOOL CALLBACK DS_GetDescEnum(LPGUID lpGuid, - LPCSTR lpstrDescription, - LPCSTR lpstrModule, + LPCWSTR lpstrDescription, + LPCWSTR lpstrModule, DirectAudioDeviceDescription* desc) { INT32 cacheIndex = findCacheItemByGUID(lpGuid, g_audioDeviceCache[desc->deviceID].isSource); if (cacheIndex == desc->deviceID) { - strncpy(desc->name, lpstrDescription, DAUDIO_STRING_LENGTH); + UnicodeToUTF8AndCopy(desc->name, lpstrDescription, DAUDIO_STRING_LENGTH); //strncpy(desc->description, lpstrModule, DAUDIO_STRING_LENGTH); desc->maxSimulLines = -1; /* do not continue enumeration */ @@ -257,10 +260,10 @@ } desc->maxSimulLines = 0; if (g_audioDeviceCache[desc->deviceID].isSource) { - DirectSoundEnumerate((LPDSENUMCALLBACK) DS_GetDescEnum, desc); + DirectSoundEnumerateW((LPDSENUMCALLBACKW) DS_GetDescEnum, desc); strncpy(desc->description, "DirectSound Playback", DAUDIO_STRING_LENGTH); } else { - DirectSoundCaptureEnumerate((LPDSENUMCALLBACK) DS_GetDescEnum, desc); + DirectSoundCaptureEnumerateW((LPDSENUMCALLBACKW) DS_GetDescEnum, desc); strncpy(desc->description, "DirectSound Capture", DAUDIO_STRING_LENGTH); } diff --git a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp --- a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp +++ b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp @@ -31,6 +31,9 @@ #include "PLATFORM_API_WinOS_Util.h" } +/* include to prevent charset problem */ +#include "PLATFORM_API_WinOS_Charset_Util.h" + #if USE_PLATFORM_MIDI_IN == TRUE #ifdef USE_ERROR @@ -248,18 +251,17 @@ return (INT32) midiInGetNumDevs(); } -INT32 getMidiInCaps(INT32 deviceID, MIDIINCAPS* caps, INT32* err) { - (*err) = midiInGetDevCaps(deviceID, caps, sizeof(MIDIINCAPS)); +INT32 getMidiInCaps(INT32 deviceID, MIDIINCAPSW* caps, INT32* err) { + (*err) = midiInGetDevCapsW(deviceID, caps, sizeof(MIDIINCAPS)); return ((*err) == MMSYSERR_NOERROR); } INT32 MIDI_IN_GetDeviceName(INT32 deviceID, char *name, UINT32 nameLength) { - MIDIINCAPS midiInCaps; + MIDIINCAPSW midiInCaps; INT32 err; if (getMidiInCaps(deviceID, &midiInCaps, &err)) { - strncpy(name, midiInCaps.szPname, nameLength-1); - name[nameLength-1] = 0; + UnicodeToUTF8AndCopy(name, midiInCaps.szPname, nameLength); return MIDI_SUCCESS; } MIDIIN_CHECK_ERROR; @@ -279,7 +281,7 @@ INT32 MIDI_IN_GetDeviceVersion(INT32 deviceID, char *name, UINT32 nameLength) { - MIDIINCAPS midiInCaps; + MIDIINCAPSW midiInCaps; INT32 err = MIDI_NOT_SUPPORTED; if (getMidiInCaps(deviceID, &midiInCaps, &err) && (nameLength>7)) { diff --git a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c --- a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c +++ b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c @@ -28,6 +28,9 @@ #include "PLATFORM_API_WinOS_Util.h" +/* include to prevent charset problem */ +#include "PLATFORM_API_WinOS_Charset_Util.h" + #if USE_PLATFORM_MIDI_OUT == TRUE @@ -66,24 +69,23 @@ } -INT32 getMidiOutCaps(INT32 deviceID, MIDIOUTCAPS* caps, INT32* err) { +INT32 getMidiOutCaps(INT32 deviceID, MIDIOUTCAPSW* caps, INT32* err) { if (deviceID == 0) { deviceID = MIDI_MAPPER; } else { deviceID--; } - (*err) = (INT32) midiOutGetDevCaps(deviceID, caps, sizeof(MIDIOUTCAPS)); + (*err) = (INT32) midiOutGetDevCapsW(deviceID, caps, sizeof(MIDIOUTCAPS)); return ((*err) == MMSYSERR_NOERROR); } INT32 MIDI_OUT_GetDeviceName(INT32 deviceID, char *name, UINT32 nameLength) { - MIDIOUTCAPS midiOutCaps; + MIDIOUTCAPSW midiOutCaps; INT32 err; if (getMidiOutCaps(deviceID, &midiOutCaps, &err)) { - strncpy(name, midiOutCaps.szPname, nameLength-1); - name[nameLength-1] = 0; + UnicodeToUTF8AndCopy(name, midiOutCaps.szPname, nameLength); return MIDI_SUCCESS; } MIDIOUT_CHECK_ERROR; @@ -97,7 +99,7 @@ INT32 MIDI_OUT_GetDeviceDescription(INT32 deviceID, char *name, UINT32 nameLength) { - MIDIOUTCAPS midiOutCaps; + MIDIOUTCAPSW midiOutCaps; char *desc; INT32 err; @@ -134,7 +136,7 @@ INT32 MIDI_OUT_GetDeviceVersion(INT32 deviceID, char *name, UINT32 nameLength) { - MIDIOUTCAPS midiOutCaps; + MIDIOUTCAPSW midiOutCaps; INT32 err; if (getMidiOutCaps(deviceID, &midiOutCaps, &err) && nameLength>7) { diff --git a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c --- a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c +++ b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c @@ -38,6 +38,9 @@ #include <mmsystem.h> #include "Ports.h" +/* include to prevent charset problem */ +#include "PLATFORM_API_WinOS_Charset_Util.h" + #if USE_PORTS == TRUE typedef struct tag_PortControlID PortControlID; @@ -353,10 +356,9 @@ ///// implemented functions of Ports.h INT32 PORT_GetPortMixerDescription(INT32 mixerIndex, PortMixerDescription* description) { - MIXERCAPS mixerCaps; - if (mixerGetDevCaps(mixerIndex, &mixerCaps, sizeof(MIXERCAPS)) == MMSYSERR_NOERROR) { - strncpy(description->name, mixerCaps.szPname, PORT_STRING_LENGTH-1); - description->name[PORT_STRING_LENGTH-1] = 0; + MIXERCAPSW mixerCaps; + if (mixerGetDevCapsW(mixerIndex, &mixerCaps, sizeof(MIXERCAPS)) == MMSYSERR_NOERROR) { + UnicodeToUTF8AndCopy(description->name, mixerCaps.szPname, PORT_STRING_LENGTH); sprintf(description->version, "%d.%d", (mixerCaps.vDriverVersion & 0xFF00) >> 8, mixerCaps.vDriverVersion & 0xFF); strncpy(description->description, "Port Mixer", PORT_STRING_LENGTH-1); return TRUE; At 2017-07-31 08:35:47, "Philip Race" <philip.r...@oracle.com> wrote: >Hi, > >1) You will need to submit the OCA before a patch can be committed. >In fact it needs to be accepted .. not just submitted ... but we can check >with the folks who manage that process once you've sent it in if you >tell us. > >2) A changeset is the wrong thing to send for review. It has to be a >patch for two reasons here >Well we can use hg --nocommit but .. if we try to push this a >server-side check >will reject it for two reasons. >#1 you do not have an author id and you have to use one to create an >acceptable changeset >#2 without a "Reviewed-by:" line, the content of which you can't >predict, the push will also fail > >-phil. > >On 7/30/17, 3:40 PM, CharlieJiang wrote: >> Hi Alex, >> >> Thanks for your reply. I'll sign the OCA soon, don't worry about it. >> I'm so sorry about the low-level mistake that I made in the code. >> Here's the new patch(just compared to the root repo instead of the previous >> patch, so you need to revert if the old patch is already applied to the >> branch): >> >> # HG changeset patch >> # User Charlie Jiang<cqjj...@126.com> >> # Date 1498382295 -28800 >> # Node ID 1bfe64cffda51c00fccf48e9c0c2adb533fa7e5c >> # Parent 2425838cfb5e63bf798e383492890c25170b91d1 >> 8177951: Charset problem when the name of the sound device contains Chinese >> character >> Summary: Fix the problem by returning the UTF-8 encoded string. >> Contributed-by: Charlie Jiang<cqjj...@126.com> >> >> diff --git >> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp >> >> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp >> --- >> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp >> +++ >> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp >> @@ -86,6 +86,28 @@ >> static UINT64 g_lastCacheRefreshTime = 0; >> static INT32 g_mixerCount = 0; >> >> +/// FIX BUG JDK-8177951: Convert ANSI encoded string to UTF-8 encoded string >> +LPCSTR ANSIToUTF8(const LPCSTR& lpAnsiStr) >> +{ >> + // ANSI -> Unicode >> + DWORD dwAnsiLen = strlen(lpAnsiStr); >> + DWORD dwUnicodeLen = ::MultiByteToWideChar(CP_ACP, 0, lpAnsiStr, -1, >> NULL, 0); >> + LPWSTR lpUnicodeStr; >> + lpUnicodeStr = new WCHAR[dwUnicodeLen]; >> + memset(lpUnicodeStr, 0, (dwUnicodeLen) * sizeof(WCHAR)); >> + MultiByteToWideChar(CP_ACP, 0, lpAnsiStr, -1, lpUnicodeStr, >> dwUnicodeLen); >> + >> + // Unicode -> UTF8 >> + LPSTR lpUTF8Str; >> + DWORD dwUTF8Len; >> + dwUTF8Len = WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, NULL, 0, >> NULL, NULL); >> + lpUTF8Str = new CHAR[dwUTF8Len]; >> + memset(lpUTF8Str, 0, sizeof(CHAR) * (dwUTF8Len)); >> + WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, lpUTF8Str, dwUTF8Len, >> NULL, NULL); >> + delete lpUnicodeStr; >> + return lpUTF8Str; >> +} >> + >> BOOL DS_lockCache() { >> /* dummy implementation for now, Java does locking */ >> return TRUE; >> @@ -233,7 +255,13 @@ >> >> INT32 cacheIndex = findCacheItemByGUID(lpGuid, >> g_audioDeviceCache[desc->deviceID].isSource); >> if (cacheIndex == desc->deviceID) { >> +#ifndef UNICODE >> + LPCSTR utf8EncodedName = ANSIToUTF8(lpstrDescription); >> + strncpy(desc->name, utf8EncodedName, DAUDIO_STRING_LENGTH); >> + delete utf8EncodedName; >> +#else >> strncpy(desc->name, lpstrDescription, DAUDIO_STRING_LENGTH); >> +#endif >> //strncpy(desc->description, lpstrModule, DAUDIO_STRING_LENGTH); >> desc->maxSimulLines = -1; >> /* do not continue enumeration */ >> # HG changeset patch >> # User Charlie Jiang<cqjj...@126.com> >> # Date 1500538314 -28800 >> # Node ID c86ae2f3e1022f9b27ad6918fa342c5a4ee309c0 >> # Parent 1bfe64cffda51c00fccf48e9c0c2adb533fa7e5c >> 8177951: Charset problem when the name of the sound device contains Chinese >> character >> Summary: Fix issues in the ANSI2UTF-8 function and move it to a seperate >> file and fix Port Sound and MIDI Sound devices. >> Contributed-by: Charlie Jiang<cqjj...@126.com> >> >> diff --git a/make/lib/SoundLibraries.gmk b/make/lib/SoundLibraries.gmk >> --- a/make/lib/SoundLibraries.gmk >> +++ b/make/lib/SoundLibraries.gmk >> @@ -61,6 +61,7 @@ >> -DUSE_PLATFORM_MIDI_IN=TRUE \ >> -DUSE_PORTS=TRUE >> LIBJSOUND_SRC_FILES += \ >> + PLATFORM_API_WinOS_Charset_Util.cpp \ >> PLATFORM_API_WinOS_MidiIn.cpp \ >> PLATFORM_API_WinOS_MidiOut.c \ >> PLATFORM_API_WinOS_Util.c \ >> @@ -190,6 +191,7 @@ >> OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ >> SRC := $(LIBJSOUND_SRC_DIRS), \ >> INCLUDE_FILES := Utilities.c $(LIBJSOUND_DAUDIOFILES) \ >> + PLATFORM_API_WinOS_Charset_Util.cpp \ >> PLATFORM_API_WinOS_DirectSound.cpp, \ >> OPTIMIZATION := LOW, \ >> CFLAGS := $(CFLAGS_JDKLIB) \ >> diff --git >> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp >> >> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp >> new file mode 100644 >> --- /dev/null >> +++ >> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp >> @@ -0,0 +1,61 @@ >> +/* >> + * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights >> reserved. >> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. >> + * >> + * This code is free software; you can redistribute it and/or modify it >> + * under the terms of the GNU General Public License version 2 only, as >> + * published by the Free Software Foundation. Oracle designates this >> + * particular file as subject to the "Classpath" exception as provided >> + * by Oracle in the LICENSE file that accompanied this code. >> + * >> + * This code is distributed in the hope that it will be useful, but WITHOUT >> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or >> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >> + * version 2 for more details (a copy is included in the LICENSE file that >> + * accompanied this code). >> + * >> + * You should have received a copy of the GNU General Public License version >> + * 2 along with this work; if not, write to the Free Software Foundation, >> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. >> + * >> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA >> + * or visit www.oracle.com if you need additional information or have any >> + * questions. >> + */ >> + >> +#include "PLATFORM_API_WinOS_Charset_Util.h" >> + >> +#include<cstring> >> + >> +extern "C" LPSTR ANSIToUTF8(const LPCSTR lpAnsiStr) >> +{ >> + // ANSI -> Unicode >> + DWORD dwUnicodeLen = 0; >> + LPWSTR lpUnicodeStr = nullptr; >> + dwUnicodeLen = MultiByteToWideChar(CP_ACP, 0, lpAnsiStr, -1, nullptr, >> 0); >> + lpUnicodeStr = new WCHAR[dwUnicodeLen]; >> + memset(lpUnicodeStr, 0, (dwUnicodeLen) * sizeof(WCHAR)); >> + MultiByteToWideChar(CP_ACP, 0, lpAnsiStr, -1, lpUnicodeStr, >> dwUnicodeLen); >> + >> + // Unicode -> UTF8 >> + LPSTR lpUTF8Str = nullptr; >> + DWORD dwUTF8Len = 0; >> + dwUTF8Len = WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, nullptr, >> 0, nullptr, nullptr); >> + lpUTF8Str = new CHAR[dwUTF8Len]; >> + memset(lpUTF8Str, 0, sizeof(CHAR) * (dwUTF8Len)); >> + WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, lpUTF8Str, dwUTF8Len, >> nullptr, nullptr); >> + delete[] lpUnicodeStr; >> + return lpUTF8Str; >> +} >> + >> +extern "C" void ANSIToUTF8IfNeededAndCopy(LPSTR dest, LPCSTR src, SIZE_T >> maxLength) { >> +#ifndef UNICODE >> + LPSTR utf8EncodedName = ANSIToUTF8(src); >> + strncpy(dest, utf8EncodedName, maxLength - 1); >> + delete[] utf8EncodedName; >> +#else >> + strncpy(dest, src, maxLength - 1); >> +#endif >> + dest[maxLength - 1] = '\0'; >> +} >> + >> \ No newline at end of file >> diff --git >> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.h >> >> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.h >> new file mode 100644 >> --- /dev/null >> +++ >> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.h >> @@ -0,0 +1,43 @@ >> +/* >> + * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights >> reserved. >> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. >> + * >> + * This code is free software; you can redistribute it and/or modify it >> + * under the terms of the GNU General Public License version 2 only, as >> + * published by the Free Software Foundation. Oracle designates this >> + * particular file as subject to the "Classpath" exception as provided >> + * by Oracle in the LICENSE file that accompanied this code. >> + * >> + * This code is distributed in the hope that it will be useful, but WITHOUT >> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or >> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >> + * version 2 for more details (a copy is included in the LICENSE file that >> + * accompanied this code). >> + * >> + * You should have received a copy of the GNU General Public License version >> + * 2 along with this work; if not, write to the Free Software Foundation, >> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. >> + * >> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA >> + * or visit www.oracle.com if you need additional information or have any >> + * questions. >> + */ >> + >> +#ifndef PLATFORM_API_WINOS_CHARSET_UTILS_H >> +#define PLATFORM_API_WINOS_CHARSET_UTILS_H >> + >> +#include<windows.h> >> + >> +#ifdef __cplusplus >> +extern "C" { >> +#endif >> + >> +LPSTR _cdecl ANSIToUTF8(const LPCSTR lpAnsiStr); >> + >> +void _cdecl ANSIToUTF8IfNeededAndCopy(LPSTR dest, LPCSTR src, SIZE_T >> maxLength); >> + >> +#ifdef __cplusplus >> +} >> +#endif >> + >> +#endif >> diff --git >> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp >> >> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp >> --- >> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp >> +++ >> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp >> @@ -52,6 +52,9 @@ >> } >> #endif >> >> +/* include to prevent charset problem */ >> +#include "PLATFORM_API_WinOS_Charset_Util.h" >> + >> #ifdef USE_DEBUG_SILENCING >> #define DEBUG_SILENCING0(p) TRACE0(p) >> #define DEBUG_SILENCING1(p1,p2) TRACE1(p1,p2) >> @@ -86,28 +89,6 @@ >> static UINT64 g_lastCacheRefreshTime = 0; >> static INT32 g_mixerCount = 0; >> >> -/// FIX BUG JDK-8177951: Convert ANSI encoded string to UTF-8 encoded string >> -LPCSTR ANSIToUTF8(const LPCSTR& lpAnsiStr) >> -{ >> - // ANSI -> Unicode >> - DWORD dwAnsiLen = strlen(lpAnsiStr); >> - DWORD dwUnicodeLen = ::MultiByteToWideChar(CP_ACP, 0, lpAnsiStr, -1, >> NULL, 0); >> - LPWSTR lpUnicodeStr; >> - lpUnicodeStr = new WCHAR[dwUnicodeLen]; >> - memset(lpUnicodeStr, 0, (dwUnicodeLen) * sizeof(WCHAR)); >> - MultiByteToWideChar(CP_ACP, 0, lpAnsiStr, -1, lpUnicodeStr, >> dwUnicodeLen); >> - >> - // Unicode -> UTF8 >> - LPSTR lpUTF8Str; >> - DWORD dwUTF8Len; >> - dwUTF8Len = WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, NULL, 0, >> NULL, NULL); >> - lpUTF8Str = new CHAR[dwUTF8Len]; >> - memset(lpUTF8Str, 0, sizeof(CHAR) * (dwUTF8Len)); >> - WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, lpUTF8Str, dwUTF8Len, >> NULL, NULL); >> - delete lpUnicodeStr; >> - return lpUTF8Str; >> -} >> - >> BOOL DS_lockCache() { >> /* dummy implementation for now, Java does locking */ >> return TRUE; >> @@ -255,13 +236,7 @@ >> >> INT32 cacheIndex = findCacheItemByGUID(lpGuid, >> g_audioDeviceCache[desc->deviceID].isSource); >> if (cacheIndex == desc->deviceID) { >> -#ifndef UNICODE >> - LPCSTR utf8EncodedName = ANSIToUTF8(lpstrDescription); >> - strncpy(desc->name, utf8EncodedName, DAUDIO_STRING_LENGTH); >> - delete utf8EncodedName; >> -#else >> - strncpy(desc->name, lpstrDescription, DAUDIO_STRING_LENGTH); >> -#endif >> + ANSIToUTF8IfNeededAndCopy(desc->name, lpstrDescription, >> DAUDIO_STRING_LENGTH); >> //strncpy(desc->description, lpstrModule, DAUDIO_STRING_LENGTH); >> desc->maxSimulLines = -1; >> /* do not continue enumeration */ >> diff --git >> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp >> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp >> --- a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp >> +++ b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp >> @@ -31,6 +31,9 @@ >> #include "PLATFORM_API_WinOS_Util.h" >> } >> >> +/* include to prevent charset problem */ >> +#include "PLATFORM_API_WinOS_Charset_Util.h" >> + >> #if USE_PLATFORM_MIDI_IN == TRUE >> >> #ifdef USE_ERROR >> @@ -258,8 +261,7 @@ >> INT32 err; >> >> if (getMidiInCaps(deviceID,&midiInCaps,&err)) { >> - strncpy(name, midiInCaps.szPname, nameLength-1); >> - name[nameLength-1] = 0; >> + ANSIToUTF8IfNeededAndCopy(name, midiInCaps.szPname, nameLength); >> return MIDI_SUCCESS; >> } >> MIDIIN_CHECK_ERROR; >> diff --git >> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c >> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c >> --- a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c >> +++ b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c >> @@ -28,6 +28,9 @@ >> >> #include "PLATFORM_API_WinOS_Util.h" >> >> +/* include to prevent charset problem */ >> +#include "PLATFORM_API_WinOS_Charset_Util.h" >> + >> #if USE_PLATFORM_MIDI_OUT == TRUE >> >> >> @@ -82,8 +85,7 @@ >> INT32 err; >> >> if (getMidiOutCaps(deviceID,&midiOutCaps,&err)) { >> - strncpy(name, midiOutCaps.szPname, nameLength-1); >> - name[nameLength-1] = 0; >> + ANSIToUTF8IfNeededAndCopy(name, midiOutCaps.szPname, nameLength); >> return MIDI_SUCCESS; >> } >> MIDIOUT_CHECK_ERROR; >> diff --git >> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c >> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c >> --- a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c >> +++ b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c >> @@ -38,6 +38,9 @@ >> #include<mmsystem.h> >> #include "Ports.h" >> >> +/* include to prevent charset problem */ >> +#include "PLATFORM_API_WinOS_Charset_Util.h" >> + >> #if USE_PORTS == TRUE >> >> typedef struct tag_PortControlID PortControlID; >> @@ -355,8 +358,7 @@ >> INT32 PORT_GetPortMixerDescription(INT32 mixerIndex, PortMixerDescription* >> description) { >> MIXERCAPS mixerCaps; >> if (mixerGetDevCaps(mixerIndex,&mixerCaps, sizeof(MIXERCAPS)) == >> MMSYSERR_NOERROR) { >> - strncpy(description->name, mixerCaps.szPname, PORT_STRING_LENGTH-1); >> - description->name[PORT_STRING_LENGTH-1] = 0; >> + ANSIToUTF8IfNeededAndCopy(description->name, mixerCaps.szPname, >> PORT_STRING_LENGTH); >> sprintf(description->version, "%d.%d", (mixerCaps.vDriverVersion& >> 0xFF00)>> 8, mixerCaps.vDriverVersion& 0xFF); >> strncpy(description->description, "Port Mixer", >> PORT_STRING_LENGTH-1); >> return TRUE; >> # HG changeset patch >> # User Charlie Jiang<cqjj...@126.com> >> # Date 1501430954 -28800 >> # Node ID 505fc2325a7192103b65fa42920e3cd06a1bdf01 >> # Parent c86ae2f3e1022f9b27ad6918fa342c5a4ee309c0 >> 8177951: Charset problem when the name of the sound device contains Chinese >> character >> Summary: See >> http://mail.openjdk.java.net/pipermail/sound-dev/2017-July/000580.html >> Contributed-by: Charlie Jiang<cqjj...@126.com> >> >> diff --git >> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp >> >> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp >> --- >> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp >> +++ >> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp >> @@ -1,5 +1,5 @@ >> /* >> - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights >> reserved. >> + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. >> * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. >> * >> * This code is free software; you can redistribute it and/or modify it >> @@ -27,35 +27,27 @@ >> >> #include<cstring> >> >> -extern "C" LPSTR ANSIToUTF8(const LPCSTR lpAnsiStr) >> -{ >> - // ANSI -> Unicode >> - DWORD dwUnicodeLen = 0; >> - LPWSTR lpUnicodeStr = nullptr; >> - dwUnicodeLen = MultiByteToWideChar(CP_ACP, 0, lpAnsiStr, -1, nullptr, >> 0); >> - lpUnicodeStr = new WCHAR[dwUnicodeLen]; >> - memset(lpUnicodeStr, 0, (dwUnicodeLen) * sizeof(WCHAR)); >> - MultiByteToWideChar(CP_ACP, 0, lpAnsiStr, -1, lpUnicodeStr, >> dwUnicodeLen); >> +#ifdef __cplusplus >> +extern "C" { >> +#endif >> >> - // Unicode -> UTF8 >> - LPSTR lpUTF8Str = nullptr; >> - DWORD dwUTF8Len = 0; >> - dwUTF8Len = WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, nullptr, >> 0, nullptr, nullptr); >> - lpUTF8Str = new CHAR[dwUTF8Len]; >> +LPSTR UnicodeToUTF8(const LPCWSTR lpUnicodeStr) >> +{ >> + DWORD dwUTF8Len = WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, >> nullptr, 0, nullptr, nullptr); >> + LPSTR lpUTF8Str = new CHAR[dwUTF8Len]; >> memset(lpUTF8Str, 0, sizeof(CHAR) * (dwUTF8Len)); >> WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, lpUTF8Str, >> dwUTF8Len, nullptr, nullptr); >> - delete[] lpUnicodeStr; >> return lpUTF8Str; >> } >> >> -extern "C" void ANSIToUTF8IfNeededAndCopy(LPSTR dest, LPCSTR src, SIZE_T >> maxLength) { >> -#ifndef UNICODE >> - LPSTR utf8EncodedName = ANSIToUTF8(src); >> +void UnicodeToUTF8AndCopy(LPSTR dest, LPCWSTR src, SIZE_T maxLength) { >> + LPSTR utf8EncodedName = UnicodeToUTF8(src); >> strncpy(dest, utf8EncodedName, maxLength - 1); >> delete[] utf8EncodedName; >> -#else >> - strncpy(dest, src, maxLength - 1); >> -#endif >> dest[maxLength - 1] = '\0'; >> } >> + >> +#ifdef __cplusplus >> +} >> +#endif >> >> \ No newline at end of file >> diff --git >> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.h >> >> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.h >> --- >> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.h >> +++ >> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.h >> @@ -1,5 +1,5 @@ >> /* >> - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights >> reserved. >> + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. >> * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. >> * >> * This code is free software; you can redistribute it and/or modify it >> @@ -32,9 +32,9 @@ >> extern "C" { >> #endif >> >> -LPSTR _cdecl ANSIToUTF8(const LPCSTR lpAnsiStr); >> +LPSTR _cdecl UnicodeToUTF8(const LPCWSTR lpAnsiStr); >> >> -void _cdecl ANSIToUTF8IfNeededAndCopy(LPSTR dest, LPCSTR src, SIZE_T >> maxLength); >> +void _cdecl UnicodeToUTF8AndCopy(LPSTR dest, LPCWSTR src, SIZE_T maxLength); >> >> #ifdef __cplusplus >> } >> diff --git >> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp >> >> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp >> --- >> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp >> +++ >> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp >> @@ -230,13 +230,13 @@ >> } >> >> BOOL CALLBACK DS_GetDescEnum(LPGUID lpGuid, >> - LPCSTR lpstrDescription, >> - LPCSTR lpstrModule, >> + LPCWSTR lpstrDescription, >> + LPCWSTR lpstrModule, >> DirectAudioDeviceDescription* desc) { >> >> INT32 cacheIndex = findCacheItemByGUID(lpGuid, >> g_audioDeviceCache[desc->deviceID].isSource); >> if (cacheIndex == desc->deviceID) { >> - ANSIToUTF8IfNeededAndCopy(desc->name, lpstrDescription, >> DAUDIO_STRING_LENGTH); >> + UnicodeToUTF8AndCopy(desc->name, lpstrDescription, >> DAUDIO_STRING_LENGTH); >> //strncpy(desc->description, lpstrModule, DAUDIO_STRING_LENGTH); >> desc->maxSimulLines = -1; >> /* do not continue enumeration */ >> @@ -260,10 +260,10 @@ >> } >> desc->maxSimulLines = 0; >> if (g_audioDeviceCache[desc->deviceID].isSource) { >> - DirectSoundEnumerate((LPDSENUMCALLBACK) DS_GetDescEnum, desc); >> + DirectSoundEnumerateW((LPDSENUMCALLBACKW) DS_GetDescEnum, desc); >> strncpy(desc->description, "DirectSound Playback", >> DAUDIO_STRING_LENGTH); >> } else { >> - DirectSoundCaptureEnumerate((LPDSENUMCALLBACK) DS_GetDescEnum, >> desc); >> + DirectSoundCaptureEnumerateW((LPDSENUMCALLBACKW) DS_GetDescEnum, >> desc); >> strncpy(desc->description, "DirectSound Capture", >> DAUDIO_STRING_LENGTH); >> } >> >> diff --git >> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp >> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp >> --- a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp >> +++ b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp >> @@ -251,17 +251,17 @@ >> return (INT32) midiInGetNumDevs(); >> } >> >> -INT32 getMidiInCaps(INT32 deviceID, MIDIINCAPS* caps, INT32* err) { >> - (*err) = midiInGetDevCaps(deviceID, caps, sizeof(MIDIINCAPS)); >> +INT32 getMidiInCaps(INT32 deviceID, MIDIINCAPSW* caps, INT32* err) { >> + (*err) = midiInGetDevCapsW(deviceID, caps, sizeof(MIDIINCAPS)); >> return ((*err) == MMSYSERR_NOERROR); >> } >> >> INT32 MIDI_IN_GetDeviceName(INT32 deviceID, char *name, UINT32 nameLength) >> { >> - MIDIINCAPS midiInCaps; >> + MIDIINCAPSW midiInCaps; >> INT32 err; >> >> if (getMidiInCaps(deviceID,&midiInCaps,&err)) { >> - ANSIToUTF8IfNeededAndCopy(name, midiInCaps.szPname, nameLength); >> + UnicodeToUTF8AndCopy(name, midiInCaps.szPname, nameLength); >> return MIDI_SUCCESS; >> } >> MIDIIN_CHECK_ERROR; >> @@ -281,7 +281,7 @@ >> >> >> INT32 MIDI_IN_GetDeviceVersion(INT32 deviceID, char *name, UINT32 >> nameLength) { >> - MIDIINCAPS midiInCaps; >> + MIDIINCAPSW midiInCaps; >> INT32 err = MIDI_NOT_SUPPORTED; >> >> if (getMidiInCaps(deviceID,&midiInCaps,&err)&& (nameLength>7)) { >> diff --git >> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c >> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c >> --- a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c >> +++ b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c >> @@ -69,23 +69,23 @@ >> } >> >> >> -INT32 getMidiOutCaps(INT32 deviceID, MIDIOUTCAPS* caps, INT32* err) { >> +INT32 getMidiOutCaps(INT32 deviceID, MIDIOUTCAPSW* caps, INT32* err) { >> if (deviceID == 0) { >> deviceID = MIDI_MAPPER; >> } else { >> deviceID--; >> } >> - (*err) = (INT32) midiOutGetDevCaps(deviceID, caps, sizeof(MIDIOUTCAPS)); >> + (*err) = (INT32) midiOutGetDevCapsW(deviceID, caps, >> sizeof(MIDIOUTCAPS)); >> return ((*err) == MMSYSERR_NOERROR); >> } >> >> >> INT32 MIDI_OUT_GetDeviceName(INT32 deviceID, char *name, UINT32 >> nameLength) { >> - MIDIOUTCAPS midiOutCaps; >> + MIDIOUTCAPSW midiOutCaps; >> INT32 err; >> >> if (getMidiOutCaps(deviceID,&midiOutCaps,&err)) { >> - ANSIToUTF8IfNeededAndCopy(name, midiOutCaps.szPname, nameLength); >> + UnicodeToUTF8AndCopy(name, midiOutCaps.szPname, nameLength); >> return MIDI_SUCCESS; >> } >> MIDIOUT_CHECK_ERROR; >> @@ -99,7 +99,7 @@ >> >> >> INT32 MIDI_OUT_GetDeviceDescription(INT32 deviceID, char *name, UINT32 >> nameLength) { >> - MIDIOUTCAPS midiOutCaps; >> + MIDIOUTCAPSW midiOutCaps; >> char *desc; >> INT32 err; >> >> @@ -136,7 +136,7 @@ >> >> >> INT32 MIDI_OUT_GetDeviceVersion(INT32 deviceID, char *name, UINT32 >> nameLength) { >> - MIDIOUTCAPS midiOutCaps; >> + MIDIOUTCAPSW midiOutCaps; >> INT32 err; >> >> if (getMidiOutCaps(deviceID,&midiOutCaps,&err)&& nameLength>7) { >> diff --git >> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c >> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c >> --- a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c >> +++ b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c >> @@ -356,9 +356,9 @@ >> ///// implemented functions of Ports.h >> >> INT32 PORT_GetPortMixerDescription(INT32 mixerIndex, PortMixerDescription* >> description) { >> - MIXERCAPS mixerCaps; >> - if (mixerGetDevCaps(mixerIndex,&mixerCaps, sizeof(MIXERCAPS)) == >> MMSYSERR_NOERROR) { >> - ANSIToUTF8IfNeededAndCopy(description->name, mixerCaps.szPname, >> PORT_STRING_LENGTH); >> + MIXERCAPSW mixerCaps; >> + if (mixerGetDevCapsW(mixerIndex,&mixerCaps, sizeof(MIXERCAPS)) == >> MMSYSERR_NOERROR) { >> + UnicodeToUTF8AndCopy(description->name, mixerCaps.szPname, >> PORT_STRING_LENGTH); >> sprintf(description->version, "%d.%d", (mixerCaps.vDriverVersion& >> 0xFF00)>> 8, mixerCaps.vDriverVersion& 0xFF); >> strncpy(description->description, "Port Mixer", >> PORT_STRING_LENGTH-1); >> return TRUE; >> >> >> At 2017-07-29 05:16:12, "Alex Menkov"<alexey.men...@oracle.com> wrote: >>> Hi Charlie, >>> >>> First of all - you have to sign OSA so Oracle may use your code. >>> >>> About the proposed fix: >>> - copyright headers contains wrong years (1999, 2012). >>> should be >>> * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. >>> >>> - do you really need 'extern "C"' stuff? Have you got some linkage >>> errors without it? >>> >>> - as I see in the code, javasound libraries cannot be compiled with >>> UNICODE, so code in "#ifdef UNICODE" doesn't make sense. >>> >>> - it would be better to define and initialize variables at the same time: >>> // ANSI -> Unicode >>> DWORD dwUnicodeLen = MultiByteToWideChar(CP_ACP, 0, lpAnsiStr, -1, >>> nullptr, 0); >>> LPWSTR lpUnicodeStr = new WCHAR[dwUnicodeLen]; >>> ... >>> // Unicode -> UTF8 >>> DWORD dwUTF8Len = WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, >>> nullptr, 0, nullptr, nullptr); >>> LPSTR lpUTF8Str = new CHAR[dwUTF8Len]; >>> >>> BTW it's not ANSI, it's ACP (Active Code Page) encoding. >>> >>> >>> - I think it would be better (and simpler) to request system to get >>> Unicode strings (by calling Unicode versions of the functions), then >>> only a single conversion (Unicode -> utf8) is required: >>> void copyUnicodeToUtf8(LPSTR dst, LPCWSTR src, size_t dstMaxSize); >>> >>> For DirectSound: >>> convert DS_GetDescEnum to LPDSENUMCALLBACKW type: >>> >>> BOOL CALLBACK DS_GetDescEnum(LPGUID lpGuid, >>> LPCWSTR lpstrDescription, >>> LPCWSTR lpstrModule, >>> DirectAudioDeviceDescription* desc) >>> ... >>> - strncpy(desc->name, lpstrDescription, DAUDIO_STRING_LENGTH); >>> + copyUnicodeToUtf8(desc->name, lpstrDescription, >>> DAUDIO_STRING_LENGTH); >>> >>> and in DAUDIO_GetDirectAudioDeviceDescription call >>> DirectSoundEnumerateW/DirectSoundCaptureEnumerateW >>> instead of DirectSoundEnumerate/DirectSoundCaptureEnumerate >>> >>> For MidiOut: >>> Use MIDIOUTCAPSW instead MIDIOUTCAPS, midiOutGetDevCapsW instead >>> midiOutGetDevCaps >>> >>> Similar changes in other files. >>> >>> --alex >>> >>> On 07/20/2017 08:50, CharlieJiang wrote: >>>> Hi Sergey, >>>> >>>> I finished writing the new patch according to your suggestions. >>>> I wrote a new source file and a header file to handle the charset problem. >>>> And I fixed this problem in all Direct devices, Ports and MIDI devices. >>>> But I don't have debugging environment of MIDI devices. >>>> So it will be very nice if somebody can test MIDI devices for me. >>>> here's the new patch, the parent changeset is the previous patch(the >>>> direct-devices only commit): >>>> >>>> >>>> # HG changeset patch >>>> # User Charlie Jiang<cqjj...@126.com> >>>> # Date 1500538314 -28800 >>>> # Node ID c86ae2f3e1022f9b27ad6918fa342c5a4ee309c0 >>>> # Parent 1bfe64cffda51c00fccf48e9c0c2adb533fa7e5c >>>> 8177951: Charset problem when the name of the sound device contains >>>> Chinese character >>>> Summary: Fix issues in the ANSI2UTF-8 function and move it to a seperate >>>> file and fix Port Sound and MIDI Sound devices. >>>> Contributed-by: Charlie Jiang<cqjj...@126.com> >>>> >>>> diff --git a/make/lib/SoundLibraries.gmk b/make/lib/SoundLibraries.gmk >>>> --- a/make/lib/SoundLibraries.gmk >>>> +++ b/make/lib/SoundLibraries.gmk >>>> @@ -61,6 +61,7 @@ >>>> -DUSE_PLATFORM_MIDI_IN=TRUE \ >>>> -DUSE_PORTS=TRUE >>>> LIBJSOUND_SRC_FILES += \ >>>> + PLATFORM_API_WinOS_Charset_Util.cpp \ >>>> PLATFORM_API_WinOS_MidiIn.cpp \ >>>> PLATFORM_API_WinOS_MidiOut.c \ >>>> PLATFORM_API_WinOS_Util.c \ >>>> @@ -190,6 +191,7 @@ >>>> OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ >>>> SRC := $(LIBJSOUND_SRC_DIRS), \ >>>> INCLUDE_FILES := Utilities.c $(LIBJSOUND_DAUDIOFILES) \ >>>> + PLATFORM_API_WinOS_Charset_Util.cpp \ >>>> PLATFORM_API_WinOS_DirectSound.cpp, \ >>>> OPTIMIZATION := LOW, \ >>>> CFLAGS := $(CFLAGS_JDKLIB) \ >>>> diff --git >>>> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp >>>> >>>> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp >>>> new file mode 100644 >>>> --- /dev/null >>>> +++ >>>> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp >>>> @@ -0,0 +1,61 @@ >>>> +/* >>>> + * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights >>>> reserved. >>>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. >>>> + * >>>> + * This code is free software; you can redistribute it and/or modify it >>>> + * under the terms of the GNU General Public License version 2 only, as >>>> + * published by the Free Software Foundation. Oracle designates this >>>> + * particular file as subject to the "Classpath" exception as provided >>>> + * by Oracle in the LICENSE file that accompanied this code. >>>> + * >>>> + * This code is distributed in the hope that it will be useful, but >>>> WITHOUT >>>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or >>>> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >>>> + * version 2 for more details (a copy is included in the LICENSE file that >>>> + * accompanied this code). >>>> + * >>>> + * You should have received a copy of the GNU General Public License >>>> version >>>> + * 2 along with this work; if not, write to the Free Software Foundation, >>>> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. >>>> + * >>>> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA >>>> + * or visit www.oracle.com if you need additional information or have any >>>> + * questions. >>>> + */ >>>> + >>>> +#include "PLATFORM_API_WinOS_Charset_Util.h" >>>> + >>>> +#include<cstring> >>>> + >>>> +extern "C" LPSTR ANSIToUTF8(const LPCSTR lpAnsiStr) >>>> +{ >>>> + // ANSI -> Unicode >>>> + DWORD dwUnicodeLen = 0; >>>> + LPWSTR lpUnicodeStr = nullptr; >>>> + dwUnicodeLen = MultiByteToWideChar(CP_ACP, 0, lpAnsiStr, -1, nullptr, >>>> 0); >>>> + lpUnicodeStr = new WCHAR[dwUnicodeLen]; >>>> + memset(lpUnicodeStr, 0, (dwUnicodeLen) * sizeof(WCHAR)); >>>> + MultiByteToWideChar(CP_ACP, 0, lpAnsiStr, -1, lpUnicodeStr, >>>> dwUnicodeLen); >>>> + >>>> + // Unicode -> UTF8 >>>> + LPSTR lpUTF8Str = nullptr; >>>> + DWORD dwUTF8Len = 0; >>>> + dwUTF8Len = WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, >>>> nullptr, 0, nullptr, nullptr); >>>> + lpUTF8Str = new CHAR[dwUTF8Len]; >>>> + memset(lpUTF8Str, 0, sizeof(CHAR) * (dwUTF8Len)); >>>> + WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, lpUTF8Str, >>>> dwUTF8Len, nullptr, nullptr); >>>> + delete[] lpUnicodeStr; >>>> + return lpUTF8Str; >>>> +} >>>> + >>>> +extern "C" void ANSIToUTF8IfNeededAndCopy(LPSTR dest, LPCSTR src, SIZE_T >>>> maxLength) { >>>> +#ifndef UNICODE >>>> + LPSTR utf8EncodedName = ANSIToUTF8(src); >>>> + strncpy(dest, utf8EncodedName, maxLength - 1); >>>> + delete[] utf8EncodedName; >>>> +#else >>>> + strncpy(dest, src, maxLength - 1); >>>> +#endif >>>> + dest[maxLength - 1] = '\0'; >>>> +} >>>> + >>>> \ No newline at end of file >>>> diff --git >>>> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.h >>>> >>>> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.h >>>> new file mode 100644 >>>> --- /dev/null >>>> +++ >>>> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.h >>>> @@ -0,0 +1,43 @@ >>>> +/* >>>> + * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights >>>> reserved. >>>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. >>>> + * >>>> + * This code is free software; you can redistribute it and/or modify it >>>> + * under the terms of the GNU General Public License version 2 only, as >>>> + * published by the Free Software Foundation. Oracle designates this >>>> + * particular file as subject to the "Classpath" exception as provided >>>> + * by Oracle in the LICENSE file that accompanied this code. >>>> + * >>>> + * This code is distributed in the hope that it will be useful, but >>>> WITHOUT >>>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or >>>> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >>>> + * version 2 for more details (a copy is included in the LICENSE file that >>>> + * accompanied this code). >>>> + * >>>> + * You should have received a copy of the GNU General Public License >>>> version >>>> + * 2 along with this work; if not, write to the Free Software Foundation, >>>> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. >>>> + * >>>> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA >>>> + * or visit www.oracle.com if you need additional information or have any >>>> + * questions. >>>> + */ >>>> + >>>> +#ifndef PLATFORM_API_WINOS_CHARSET_UTILS_H >>>> +#define PLATFORM_API_WINOS_CHARSET_UTILS_H >>>> + >>>> +#include<windows.h> >>>> + >>>> +#ifdef __cplusplus >>>> +extern "C" { >>>> +#endif >>>> + >>>> +LPSTR _cdecl ANSIToUTF8(const LPCSTR lpAnsiStr); >>>> + >>>> +void _cdecl ANSIToUTF8IfNeededAndCopy(LPSTR dest, LPCSTR src, SIZE_T >>>> maxLength); >>>> + >>>> +#ifdef __cplusplus >>>> +} >>>> +#endif >>>> + >>>> +#endif >>>> diff --git >>>> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp >>>> >>>> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp >>>> --- >>>> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp >>>> +++ >>>> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp >>>> @@ -52,6 +52,9 @@ >>>> } >>>> #endif >>>> >>>> +/* include to prevent charset problem */ >>>> +#include "PLATFORM_API_WinOS_Charset_Util.h" >>>> + >>>> #ifdef USE_DEBUG_SILENCING >>>> #define DEBUG_SILENCING0(p) TRACE0(p) >>>> #define DEBUG_SILENCING1(p1,p2) TRACE1(p1,p2) >>>> @@ -86,28 +89,6 @@ >>>> static UINT64 g_lastCacheRefreshTime = 0; >>>> static INT32 g_mixerCount = 0; >>>> >>>> -/// FIX BUG JDK-8177951: Convert ANSI encoded string to UTF-8 encoded >>>> string >>>> -LPCSTR ANSIToUTF8(const LPCSTR& lpAnsiStr) >>>> -{ >>>> - // ANSI -> Unicode >>>> - DWORD dwAnsiLen = strlen(lpAnsiStr); >>>> - DWORD dwUnicodeLen = ::MultiByteToWideChar(CP_ACP, 0, lpAnsiStr, -1, >>>> NULL, 0); >>>> - LPWSTR lpUnicodeStr; >>>> - lpUnicodeStr = new WCHAR[dwUnicodeLen]; >>>> - memset(lpUnicodeStr, 0, (dwUnicodeLen) * sizeof(WCHAR)); >>>> - MultiByteToWideChar(CP_ACP, 0, lpAnsiStr, -1, lpUnicodeStr, >>>> dwUnicodeLen); >>>> - >>>> - // Unicode -> UTF8 >>>> - LPSTR lpUTF8Str; >>>> - DWORD dwUTF8Len; >>>> - dwUTF8Len = WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, NULL, >>>> 0, NULL, NULL); >>>> - lpUTF8Str = new CHAR[dwUTF8Len]; >>>> - memset(lpUTF8Str, 0, sizeof(CHAR) * (dwUTF8Len)); >>>> - WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, lpUTF8Str, >>>> dwUTF8Len, NULL, NULL); >>>> - delete lpUnicodeStr; >>>> - return lpUTF8Str; >>>> -} >>>> - >>>> BOOL DS_lockCache() { >>>> /* dummy implementation for now, Java does locking */ >>>> return TRUE; >>>> @@ -255,13 +236,7 @@ >>>> >>>> INT32 cacheIndex = findCacheItemByGUID(lpGuid, >>>> g_audioDeviceCache[desc->deviceID].isSource); >>>> if (cacheIndex == desc->deviceID) { >>>> -#ifndef UNICODE >>>> - LPCSTR utf8EncodedName = ANSIToUTF8(lpstrDescription); >>>> - strncpy(desc->name, utf8EncodedName, DAUDIO_STRING_LENGTH); >>>> - delete utf8EncodedName; >>>> -#else >>>> - strncpy(desc->name, lpstrDescription, DAUDIO_STRING_LENGTH); >>>> -#endif >>>> + ANSIToUTF8IfNeededAndCopy(desc->name, lpstrDescription, >>>> DAUDIO_STRING_LENGTH); >>>> //strncpy(desc->description, lpstrModule, DAUDIO_STRING_LENGTH); >>>> desc->maxSimulLines = -1; >>>> /* do not continue enumeration */ >>>> diff --git >>>> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp >>>> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp >>>> --- >>>> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp >>>> +++ >>>> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp >>>> @@ -31,6 +31,9 @@ >>>> #include "PLATFORM_API_WinOS_Util.h" >>>> } >>>> >>>> +/* include to prevent charset problem */ >>>> +#include "PLATFORM_API_WinOS_Charset_Util.h" >>>> + >>>> #if USE_PLATFORM_MIDI_IN == TRUE >>>> >>>> #ifdef USE_ERROR >>>> @@ -258,8 +261,7 @@ >>>> INT32 err; >>>> >>>> if (getMidiInCaps(deviceID,&midiInCaps,&err)) { >>>> - strncpy(name, midiInCaps.szPname, nameLength-1); >>>> - name[nameLength-1] = 0; >>>> + ANSIToUTF8IfNeededAndCopy(name, midiInCaps.szPname, nameLength); >>>> return MIDI_SUCCESS; >>>> } >>>> MIDIIN_CHECK_ERROR; >>>> diff --git >>>> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c >>>> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c >>>> --- >>>> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c >>>> +++ >>>> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c >>>> @@ -28,6 +28,9 @@ >>>> >>>> #include "PLATFORM_API_WinOS_Util.h" >>>> >>>> +/* include to prevent charset problem */ >>>> +#include "PLATFORM_API_WinOS_Charset_Util.h" >>>> + >>>> #if USE_PLATFORM_MIDI_OUT == TRUE >>>> >>>> >>>> @@ -82,8 +85,7 @@ >>>> INT32 err; >>>> >>>> if (getMidiOutCaps(deviceID,&midiOutCaps,&err)) { >>>> - strncpy(name, midiOutCaps.szPname, nameLength-1); >>>> - name[nameLength-1] = 0; >>>> + ANSIToUTF8IfNeededAndCopy(name, midiOutCaps.szPname, nameLength); >>>> return MIDI_SUCCESS; >>>> } >>>> MIDIOUT_CHECK_ERROR; >>>> diff --git >>>> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c >>>> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c >>>> --- a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c >>>> +++ b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c >>>> @@ -38,6 +38,9 @@ >>>> #include<mmsystem.h> >>>> #include "Ports.h" >>>> >>>> +/* include to prevent charset problem */ >>>> +#include "PLATFORM_API_WinOS_Charset_Util.h" >>>> + >>>> #if USE_PORTS == TRUE >>>> >>>> typedef struct tag_PortControlID PortControlID; >>>> @@ -355,8 +358,7 @@ >>>> INT32 PORT_GetPortMixerDescription(INT32 mixerIndex, >>>> PortMixerDescription* description) { >>>> MIXERCAPS mixerCaps; >>>> if (mixerGetDevCaps(mixerIndex,&mixerCaps, sizeof(MIXERCAPS)) == >>>> MMSYSERR_NOERROR) { >>>> - strncpy(description->name, mixerCaps.szPname, >>>> PORT_STRING_LENGTH-1); >>>> - description->name[PORT_STRING_LENGTH-1] = 0; >>>> + ANSIToUTF8IfNeededAndCopy(description->name, mixerCaps.szPname, >>>> PORT_STRING_LENGTH); >>>> sprintf(description->version, "%d.%d", >>>> (mixerCaps.vDriverVersion& 0xFF00)>> 8, mixerCaps.vDriverVersion& 0xFF); >>>> strncpy(description->description, "Port Mixer", >>>> PORT_STRING_LENGTH-1); >>>> return TRUE; >>>> >>>> >>>> =================================================================================================== >>>> =================================EOF=============================================================== >>>> =================================================================================================== >>>> >>>> >>>> And if you need a patch that can be directly applied to the root repo, >>>> then use this: >>>> >>>> >>>> diff --git a/make/lib/SoundLibraries.gmk b/make/lib/SoundLibraries.gmk >>>> --- a/make/lib/SoundLibraries.gmk >>>> +++ b/make/lib/SoundLibraries.gmk >>>> @@ -61,6 +61,7 @@ >>>> -DUSE_PLATFORM_MIDI_IN=TRUE \ >>>> -DUSE_PORTS=TRUE >>>> LIBJSOUND_SRC_FILES += \ >>>> + PLATFORM_API_WinOS_Charset_Util.cpp \ >>>> PLATFORM_API_WinOS_MidiIn.cpp \ >>>> PLATFORM_API_WinOS_MidiOut.c \ >>>> PLATFORM_API_WinOS_Util.c \ >>>> @@ -190,6 +191,7 @@ >>>> OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ >>>> SRC := $(LIBJSOUND_SRC_DIRS), \ >>>> INCLUDE_FILES := Utilities.c $(LIBJSOUND_DAUDIOFILES) \ >>>> + PLATFORM_API_WinOS_Charset_Util.cpp \ >>>> PLATFORM_API_WinOS_DirectSound.cpp, \ >>>> OPTIMIZATION := LOW, \ >>>> CFLAGS := $(CFLAGS_JDKLIB) \ >>>> diff --git >>>> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp >>>> >>>> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp >>>> new file mode 100644 >>>> --- /dev/null >>>> +++ >>>> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp >>>> @@ -0,0 +1,61 @@ >>>> +/* >>>> + * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights >>>> reserved. >>>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. >>>> + * >>>> + * This code is free software; you can redistribute it and/or modify it >>>> + * under the terms of the GNU General Public License version 2 only, as >>>> + * published by the Free Software Foundation. Oracle designates this >>>> + * particular file as subject to the "Classpath" exception as provided >>>> + * by Oracle in the LICENSE file that accompanied this code. >>>> + * >>>> + * This code is distributed in the hope that it will be useful, but >>>> WITHOUT >>>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or >>>> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >>>> + * version 2 for more details (a copy is included in the LICENSE file that >>>> + * accompanied this code). >>>> + * >>>> + * You should have received a copy of the GNU General Public License >>>> version >>>> + * 2 along with this work; if not, write to the Free Software Foundation, >>>> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. >>>> + * >>>> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA >>>> + * or visit www.oracle.com if you need additional information or have any >>>> + * questions. >>>> + */ >>>> + >>>> +#include "PLATFORM_API_WinOS_Charset_Util.h" >>>> + >>>> +#include<cstring> >>>> + >>>> +extern "C" LPSTR ANSIToUTF8(const LPCSTR lpAnsiStr) >>>> +{ >>>> + // ANSI -> Unicode >>>> + DWORD dwUnicodeLen = 0; >>>> + LPWSTR lpUnicodeStr = nullptr; >>>> + dwUnicodeLen = MultiByteToWideChar(CP_ACP, 0, lpAnsiStr, -1, nullptr, >>>> 0); >>>> + lpUnicodeStr = new WCHAR[dwUnicodeLen]; >>>> + memset(lpUnicodeStr, 0, (dwUnicodeLen) * sizeof(WCHAR)); >>>> + MultiByteToWideChar(CP_ACP, 0, lpAnsiStr, -1, lpUnicodeStr, >>>> dwUnicodeLen); >>>> + >>>> + // Unicode -> UTF8 >>>> + LPSTR lpUTF8Str = nullptr; >>>> + DWORD dwUTF8Len = 0; >>>> + dwUTF8Len = WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, >>>> nullptr, 0, nullptr, nullptr); >>>> + lpUTF8Str = new CHAR[dwUTF8Len]; >>>> + memset(lpUTF8Str, 0, sizeof(CHAR) * (dwUTF8Len)); >>>> + WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, lpUTF8Str, >>>> dwUTF8Len, nullptr, nullptr); >>>> + delete[] lpUnicodeStr; >>>> + return lpUTF8Str; >>>> +} >>>> + >>>> +extern "C" void ANSIToUTF8IfNeededAndCopy(LPSTR dest, LPCSTR src, SIZE_T >>>> maxLength) { >>>> +#ifndef UNICODE >>>> + LPSTR utf8EncodedName = ANSIToUTF8(src); >>>> + strncpy(dest, utf8EncodedName, maxLength - 1); >>>> + delete[] utf8EncodedName; >>>> +#else >>>> + strncpy(dest, src, maxLength - 1); >>>> +#endif >>>> + dest[maxLength - 1] = '\0'; >>>> +} >>>> + >>>> \ No newline at end of file >>>> diff --git >>>> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.h >>>> >>>> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.h >>>> new file mode 100644 >>>> --- /dev/null >>>> +++ >>>> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.h >>>> @@ -0,0 +1,43 @@ >>>> +/* >>>> + * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights >>>> reserved. >>>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. >>>> + * >>>> + * This code is free software; you can redistribute it and/or modify it >>>> + * under the terms of the GNU General Public License version 2 only, as >>>> + * published by the Free Software Foundation. Oracle designates this >>>> + * particular file as subject to the "Classpath" exception as provided >>>> + * by Oracle in the LICENSE file that accompanied this code. >>>> + * >>>> + * This code is distributed in the hope that it will be useful, but >>>> WITHOUT >>>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or >>>> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License >>>> + * version 2 for more details (a copy is included in the LICENSE file that >>>> + * accompanied this code). >>>> + * >>>> + * You should have received a copy of the GNU General Public License >>>> version >>>> + * 2 along with this work; if not, write to the Free Software Foundation, >>>> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. >>>> + * >>>> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA >>>> + * or visit www.oracle.com if you need additional information or have any >>>> + * questions. >>>> + */ >>>> + >>>> +#ifndef PLATFORM_API_WINOS_CHARSET_UTILS_H >>>> +#define PLATFORM_API_WINOS_CHARSET_UTILS_H >>>> + >>>> +#include<windows.h> >>>> + >>>> +#ifdef __cplusplus >>>> +extern "C" { >>>> +#endif >>>> + >>>> +LPSTR _cdecl ANSIToUTF8(const LPCSTR lpAnsiStr); >>>> + >>>> +void _cdecl ANSIToUTF8IfNeededAndCopy(LPSTR dest, LPCSTR src, SIZE_T >>>> maxLength); >>>> + >>>> +#ifdef __cplusplus >>>> +} >>>> +#endif >>>> + >>>> +#endif >>>> diff --git >>>> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp >>>> >>>> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp >>>> --- >>>> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp >>>> +++ >>>> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp >>>> @@ -52,6 +52,9 @@ >>>> } >>>> #endif >>>> >>>> +/* include to prevent charset problem */ >>>> +#include "PLATFORM_API_WinOS_Charset_Util.h" >>>> + >>>> #ifdef USE_DEBUG_SILENCING >>>> #define DEBUG_SILENCING0(p) TRACE0(p) >>>> #define DEBUG_SILENCING1(p1,p2) TRACE1(p1,p2) >>>> @@ -233,7 +236,7 @@ >>>> >>>> INT32 cacheIndex = findCacheItemByGUID(lpGuid, >>>> g_audioDeviceCache[desc->deviceID].isSource); >>>> if (cacheIndex == desc->deviceID) { >>>> - strncpy(desc->name, lpstrDescription, DAUDIO_STRING_LENGTH); >>>> + ANSIToUTF8IfNeededAndCopy(desc->name, lpstrDescription, >>>> DAUDIO_STRING_LENGTH); >>>> //strncpy(desc->description, lpstrModule, DAUDIO_STRING_LENGTH); >>>> desc->maxSimulLines = -1; >>>> /* do not continue enumeration */ >>>> diff --git >>>> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp >>>> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp >>>> --- >>>> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp >>>> +++ >>>> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp >>>> @@ -31,6 +31,9 @@ >>>> #include "PLATFORM_API_WinOS_Util.h" >>>> } >>>> >>>> +/* include to prevent charset problem */ >>>> +#include "PLATFORM_API_WinOS_Charset_Util.h" >>>> + >>>> #if USE_PLATFORM_MIDI_IN == TRUE >>>> >>>> #ifdef USE_ERROR >>>> @@ -258,8 +261,7 @@ >>>> INT32 err; >>>> >>>> if (getMidiInCaps(deviceID,&midiInCaps,&err)) { >>>> - strncpy(name, midiInCaps.szPname, nameLength-1); >>>> - name[nameLength-1] = 0; >>>> + ANSIToUTF8IfNeededAndCopy(name, midiInCaps.szPname, nameLength); >>>> return MIDI_SUCCESS; >>>> } >>>> MIDIIN_CHECK_ERROR; >>>> diff --git >>>> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c >>>> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c >>>> --- >>>> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c >>>> +++ >>>> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c >>>> @@ -28,6 +28,9 @@ >>>> >>>> #include "PLATFORM_API_WinOS_Util.h" >>>> >>>> +/* include to prevent charset problem */ >>>> +#include "PLATFORM_API_WinOS_Charset_Util.h" >>>> + >>>> #if USE_PLATFORM_MIDI_OUT == TRUE >>>> >>>> >>>> @@ -82,8 +85,7 @@ >>>> INT32 err; >>>> >>>> if (getMidiOutCaps(deviceID,&midiOutCaps,&err)) { >>>> - strncpy(name, midiOutCaps.szPname, nameLength-1); >>>> - name[nameLength-1] = 0; >>>> + ANSIToUTF8IfNeededAndCopy(name, midiOutCaps.szPname, nameLength); >>>> return MIDI_SUCCESS; >>>> } >>>> MIDIOUT_CHECK_ERROR; >>>> diff --git >>>> a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c >>>> b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c >>>> --- a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c >>>> +++ b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c >>>> @@ -38,6 +38,9 @@ >>>> #include<mmsystem.h> >>>> #include "Ports.h" >>>> >>>> +/* include to prevent charset problem */ >>>> +#include "PLATFORM_API_WinOS_Charset_Util.h" >>>> + >>>> #if USE_PORTS == TRUE >>>> >>>> typedef struct tag_PortControlID PortControlID; >>>> @@ -355,8 +358,7 @@ >>>> INT32 PORT_GetPortMixerDescription(INT32 mixerIndex, >>>> PortMixerDescription* description) { >>>> MIXERCAPS mixerCaps; >>>> if (mixerGetDevCaps(mixerIndex,&mixerCaps, sizeof(MIXERCAPS)) == >>>> MMSYSERR_NOERROR) { >>>> - strncpy(description->name, mixerCaps.szPname, >>>> PORT_STRING_LENGTH-1); >>>> - description->name[PORT_STRING_LENGTH-1] = 0; >>>> + ANSIToUTF8IfNeededAndCopy(description->name, mixerCaps.szPname, >>>> PORT_STRING_LENGTH); >>>> sprintf(description->version, "%d.%d", >>>> (mixerCaps.vDriverVersion& 0xFF00)>> 8, mixerCaps.vDriverVersion& 0xFF); >>>> strncpy(description->description, "Port Mixer", >>>> PORT_STRING_LENGTH-1); >>>> return TRUE; >>>> >>>> >>>> About the issue of the OCA, because actually I won't often push code to >>>> the OpenJDK repo, >>>> so I think it's unnecessary to join the OCB now, and the steps to join it >>>> is pretty complex. >>>> >>>> Cheers, >>>> Charlie Jiang >>>> 2017-7-20 >>>> >>>> PS: a picture of the effect of the new patch: >>>> http://imgur.com/a/SjlAU >>>> >>>> =================================================================================================== >>>> =================================EOF=============================================================== >>>> =================================================================================================== >>>> >>>> >>>> At 2017-07-18 08:38:15, "Sergey Bylokhov"<sergey.bylok...@oracle.com> >>>> wrote: >>>> >>>> p { margin: 0; } >>>> Hello. >>>> I uploaded the current patch to cr.openjdk: >>>> http://cr.openjdk.java.net/~serb/8177951/webrev.00 >>>> >>>> I have tested the patch and here is my observation: >>>> - The patch works for direct devices, but it looks like the same bug >>>> exists in Ports(also reproduced by your testcase), did you have a chance >>>> to look into this issue as well? >>>> - jdk uses "warning-as-error" policy during the build, so currently >>>> there is a build failure, because of this warning: >>>> PLATFORM_API_WinOS_DirectSound.cpp(93) : warning C4267: >>>> 'initializing' : conversion from 'size_t' to 'DWORD', possible loss of data >>>> - Note that the memory which is allocated by "new[]" should be >>>> deallocated by the "delete[]", but current fix use simple "delete". >>>> - Can you please sign and submit the OCA[1], which will allow you to >>>> contribute to the openjdk? >>>> >>>> [1] http://www.oracle.com/technetwork/community/oca-486395.html >>>> >>>> >>>> ----- cqjj...@126.com wrote: >>>> >>>>> >>>> Hello, >>>> Please review this bug report: >>>> https://bugs.openjdk.java.net/browse/JDK-8177951 >>>> >>>> A brief description of the issue: >>>> In non-English Windows, the DirectAudioDeviceProvider can't work properly, >>>> AudioSystem.getMixerInfo()[0].getName() (or any other index, as long as >>>> the name of mixer contains non-ASCII characters)will return a corrupted >>>> string (all non-ASCII chars become messy codes). >>>> The main reason is in native codes, we get a string in >>>> ANSI(platform-dependent) charset. But in the code the string is just >>>> processed as a UTF-8 string. So the JVM encodes ANSI string by UTF-8 >>>> encoding. >>>> >>>> Detailed description: >>>> The performace of the bug is contained in the link above, I'll talk about >>>> the reason of the issue. All research below are based on OpenJDK 9, but I >>>> think OpenJDK 8 is also applicable. >>>> >>>> In >>>> jdk/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp, >>>> Function DS_GetDesc_Enum, Line 236, the name of the device is >>>> gotten(called by function DirectSoundDeviceEnumerate) from the OS, in ANSI >>>> charset, in a LPCSTR. And you just copy the ANSI encoded string to the >>>> DirectAudioDeviceDescription struct. So let's look at the >>>> jdk/src/java.desktop/share/native/libjsound/DirectAudioDeviceProvider.c, >>>> Function getDirectAudioDeviceDescription and >>>> Java_com_sun_media_sound_DirectAudioDeviceProvider_nNewDirectAudioDeviceInfo, >>>> Line 48 and 98, you called NewStringUTF function with a ANSI encoded >>>> string. So we got a UTF-8 encoded ANSI string. But obviously we need a >>>> UTF-8 encoded Unicode String. >>>> >>>> I wrote to Oracle but they can't reproduce the issue, so I went on fixing >>>> the bug by myself. I wrote a function to convert ANSI string to UTF-8 >>>> encoded Unicode string. >>>> >>>> And I found a problem: In Multi-Byte compiling mode, >>>> DirectSoundDeviceEnumerate will call DirectSoundDeviceEnumerateA and it >>>> will present a ANSI string as the argument, but in Unicode mode, >>>> DirectSoundDeviceEnumerate calls DirectSoundDeviceEnumerateW which >>>> presents a UTF-8 encoded Unicode string! So I think it's necessary to >>>> check if the compiler is in Unicode mode(by checking UNICODE macro), and >>>> only convert the string when it's in Multi-Byte mode. >>>> >>>> But, I don't have the debugging environment, I have problem configuring >>>> the compiler of OpenJDK. LINK : error LNK2001: unresolved external symbol >>>> _mainCRTStartup when executing ./configure script. So I can't test the >>>> validness of the patch. I'll be grateful if someone can help solve the >>>> configuring problem or test the patch for me. Even if you can compile the >>>> JDK with the patch is OK. >>>> If you'd like to test the patch, you can test it with the first device >>>> from DirectSoundDeviceEnumerate, 'Primary Sound Driver'. Maybe you don't >>>> have Chinese font, I'll attach a picture to the correct output. >>>> >>>> The patch is below and attached with the E-Mail. It's applicable for >>>> OpenJDK9, maybe 8 if you change it. >>>> https://imgur.com/a/6kgeU >>>> The code in the picture is just for generate a output, in the Unicode >>>> mode, so it's not applicable for JDK. >>>> >>>> *** >>>> old/jdk/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp >>>> 2017-06-21 03:57:42.000000000 +0800 >>>> --- >>>> new/jdk/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp >>>> 2017-06-24 16:26:57.232247800 +0800 >>>> *************** >>>> *** 86,91 **** >>>> --- 86,113 ---- >>>> static UINT64 g_lastCacheRefreshTime = 0; >>>> static INT32 g_mixerCount = 0; >>>> >>>> + /// FIX BUG JDK-8177951: Convert ANSI encoded string to UTF-8 encoded >>>> string >>>> + LPCSTR ANSIToUTF8(const LPCSTR& lpAnsiStr) >>>> + { >>>> + // ANSI -> Unicode >>>> + DWORD dwAnsiLen = strlen(lpAnsiStr); >>>> + DWORD dwUnicodeLen = ::MultiByteToWideChar(CP_ACP, 0, lpAnsiStr, -1, >>>> NULL, 0); >>>> + LPWSTR lpUnicodeStr; >>>> + lpUnicodeStr = new WCHAR[dwUnicodeLen]; >>>> + memset(lpUnicodeStr, 0, (dwUnicodeLen) * sizeof(WCHAR)); >>>> + MultiByteToWideChar(CP_ACP, 0, lpAnsiStr, -1, lpUnicodeStr, >>>> dwUnicodeLen); >>>> + >>>> + // Unicode -> UTF8 >>>> + LPSTR lpUTF8Str; >>>> + DWORD dwUTF8Len; >>>> + dwUTF8Len = WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, NULL, >>>> 0, NULL, NULL); >>>> + lpUTF8Str = new CHAR[dwUTF8Len]; >>>> + memset(lpUTF8Str, 0, sizeof(CHAR) * (dwUTF8Len)); >>>> + WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, lpUTF8Str, >>>> dwUTF8Len, NULL, NULL); >>>> + delete lpUnicodeStr; >>>> + return lpUTF8Str; >>>> + } >>>> + >>>> BOOL DS_lockCache() { >>>> /* dummy implementation for now, Java does locking */ >>>> return TRUE; >>>> *************** >>>> *** 233,239 **** >>>> --- 255,267 ---- >>>> >>>> INT32 cacheIndex = findCacheItemByGUID(lpGuid, >>>> g_audioDeviceCache[desc->deviceID].isSource); >>>> if (cacheIndex == desc->deviceID) { >>>> + #ifndef UNICODE >>>> + LPCSTR utf8EncodedName = ANSIToUTF8(lpstrDescription); >>>> + strncpy(desc->name, utf8EncodedName, DAUDIO_STRING_LENGTH); >>>> + delete utf8EncodedName; >>>> + #else >>>> strncpy(desc->name, lpstrDescription, DAUDIO_STRING_LENGTH); >>>> + #endif >>>> //strncpy(desc->description, lpstrModule, DAUDIO_STRING_LENGTH); >>>> desc->maxSimulLines = -1; >>>> /* do not continue enumeration */ >>>> >>>> Cheers, >>>> Charlie Jiang >>>>> >>>>