From cqjjjzr at 126.com Tue Aug 1 06:31:08 2017 From: cqjjjzr at 126.com (CharlieJiang) Date: Tue, 1 Aug 2017 14:31:08 +0800 (CST) Subject: 8177951: Charset problem when the name of the sound device contains Chinese character. In-Reply-To: <597E7B63.60409@oracle.com> References: <92fd9a29-de2e-4f1c-be12-5f5a4aae972f@default> <30d38b19.a924.15d60b1ab01.Coremail.cqjjjzr@126.com> <9004ea2e-7b50-1dae-3853-4f75cb44ba20@oracle.com> <1435cf32.29a.15d95a8349e.Coremail.cqjjjzr@126.com> <597E7B63.60409@oracle.com> Message-ID: <58c0e291.53d6.15d9c7dae71.Coremail.cqjjjzr@126.com> 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 " # 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 + +#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 + +#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 #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" 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 >> # 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 >> >> 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 >> # 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 >> >> 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 >> + >> +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 >> + >> +#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 >> #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 >> # 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 >> >> 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 >> >> -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" 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 >>>> # 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 >>>> >>>> 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 >>>> + >>>> +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 >>>> + >>>> +#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 >>>> #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 >>>> + >>>> +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 >>>> + >>>> +#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 >>>> #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" 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 >>>> >>>> >>>> ----- cqjjjzr at 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 >>>>> >>>> From cqjjjzr at 126.com Tue Aug 8 09:13:49 2017 From: cqjjjzr at 126.com (CharlieJiang) Date: Tue, 8 Aug 2017 17:13:49 +0800 (CST) Subject: 8177951: Charset problem when the name of the sound device contains Chinese character. In-Reply-To: <597E7B63.60409@oracle.com> References: <92fd9a29-de2e-4f1c-be12-5f5a4aae972f@default> <30d38b19.a924.15d60b1ab01.Coremail.cqjjjzr@126.com> <9004ea2e-7b50-1dae-3853-4f75cb44ba20@oracle.com> <1435cf32.29a.15d95a8349e.Coremail.cqjjjzr@126.com> <597E7B63.60409@oracle.com> Message-ID: <790a70ac.7a5f.15dc11f242a.Coremail.cqjjjzr@126.com> Hi, My OCA request is accepted, so I think you can start the reviewing progress. Cheers, Charlie Jiang At 2017-07-31 08:35:47, "Philip Race" 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 >> # 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 >> >> 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 >> # 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 >> >> 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 >> + >> +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 >> + >> +#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 >> #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 >> # 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 >> >> 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 >> >> -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" 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 >>>> # 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 >>>> >>>> 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 >>>> + >>>> +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 >>>> + >>>> +#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 >>>> #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 >>>> + >>>> +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 >>>> + >>>> +#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 >>>> #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" 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 >>>> >>>> >>>> ----- cqjjjzr at 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 >>>>> >>>> From stefan.reich.maker.of.eye at googlemail.com Mon Aug 14 13:24:27 2017 From: stefan.reich.maker.of.eye at googlemail.com (Stefan Reich) Date: Mon, 14 Aug 2017 15:24:27 +0200 Subject: JavaSound is not actually usable on Oracle JDK Message-ID: Hi there, I am currently using JavaSound on Oracle JDK 1.8 on Linux and Windows. It's an unmitigated catastrophe. Something as simple as playing a Clip only works 60% of the time. The other times, it just stays mute. This may not be your fault as I'm not currently using OpenJDK. How different is the OpenJDK code base versus Oracle relating to JavaSound? Should I try OpenJDK again? The background is: I really want to support every end user out there, so both OpenJDK and Oracle JDK should run my software well... I am working around the issue by actually invoking command line tools (aplay on Linux, cmdmp3.exe on Windows) for playing sounds. Perfect? Hell no. But JavaSound really is too thoroughly broken, at least on Oracle JDK. Sorry for the harsh words. Where is the way out? All the best, Stefan -- Stefan Reich BotCompany.de -------------- next part -------------- An HTML attachment was scrubbed... URL: From contact at petersalomonsen.com Mon Aug 14 14:03:09 2017 From: contact at petersalomonsen.com (Peter Salomonsen) Date: Mon, 14 Aug 2017 16:03:09 +0200 Subject: JavaSound is not actually usable on Oracle JDK In-Reply-To: References: Message-ID: Hi! Frinika (frinika.com) runs well on OracleJDK and OpenJDK, both Linux, Windows and OSX. Uses most of Javasound capabilities, not so much clip, but pretty much everything else. Have you got some example code of what doesn't work for you? best regards, Peter 2017-08-14 15:24 GMT+02:00 Stefan Reich < stefan.reich.maker.of.eye at googlemail.com>: > Hi there, > > I am currently using JavaSound on Oracle JDK 1.8 on Linux and Windows. > It's an unmitigated catastrophe. > > Something as simple as playing a Clip only works 60% of the time. The > other times, it just stays mute. > > This may not be your fault as I'm not currently using OpenJDK. How > different is the OpenJDK code base versus Oracle relating to JavaSound? > > Should I try OpenJDK again? > > The background is: I really want to support every end user out there, so > both OpenJDK and Oracle JDK should run my software well... > > I am working around the issue by actually invoking command line tools > (aplay on Linux, cmdmp3.exe on Windows) for playing sounds. Perfect? Hell > no. But JavaSound really is too thoroughly broken, at least on Oracle JDK. > > Sorry for the harsh words. Where is the way out? > > All the best, > Stefan > > -- > Stefan Reich > BotCompany.de > -------------- next part -------------- An HTML attachment was scrubbed... URL: From damjan.jov at gmail.com Mon Aug 14 14:08:11 2017 From: damjan.jov at gmail.com (Damjan Jovanovic) Date: Mon, 14 Aug 2017 16:08:11 +0200 Subject: JavaSound is not actually usable on Oracle JDK In-Reply-To: References: Message-ID: Which Linux distribution are you using? On at leaset Ubuntu the default jre/lib/sound.properties for OpenJDK only contains these lines: javax.sound.sampled.Clip=org.classpath.icedtea.pulseaudio.PulseAudioMixerProvider javax.sound.sampled.Port=org.classpath.icedtea.pulseaudio.PulseAudioMixerProvider javax.sound.sampled.SourceDataLine=org.classpath.icedtea.pulseaudio.PulseAudioMixerProvider javax.sound.sampled.TargetDataLine=org.classpath.icedtea.pulseaudio.PulseAudioMixerProvider so it's using IcedTea's PulseAudio driver instead of Oracle's ALSA driver. That may account for the difference you are seeing. Regards Damjan On Mon, Aug 14, 2017 at 3:24 PM, Stefan Reich < stefan.reich.maker.of.eye at googlemail.com> wrote: > Hi there, > > I am currently using JavaSound on Oracle JDK 1.8 on Linux and Windows. > It's an unmitigated catastrophe. > > Something as simple as playing a Clip only works 60% of the time. The > other times, it just stays mute. > > This may not be your fault as I'm not currently using OpenJDK. How > different is the OpenJDK code base versus Oracle relating to JavaSound? > > Should I try OpenJDK again? > > The background is: I really want to support every end user out there, so > both OpenJDK and Oracle JDK should run my software well... > > I am working around the issue by actually invoking command line tools > (aplay on Linux, cmdmp3.exe on Windows) for playing sounds. Perfect? Hell > no. But JavaSound really is too thoroughly broken, at least on Oracle JDK. > > Sorry for the harsh words. Where is the way out? > > All the best, > Stefan > > -- > Stefan Reich > BotCompany.de > -------------- next part -------------- An HTML attachment was scrubbed... URL: From philip.race at oracle.com Mon Aug 14 16:19:52 2017 From: philip.race at oracle.com (Phil Race) Date: Mon, 14 Aug 2017 09:19:52 -0700 Subject: JavaSound is not actually usable on Oracle JDK In-Reply-To: References: Message-ID: There is no difference between Oracle JDK and OpenJDK Java Sound sources. -phil. On 08/14/2017 06:24 AM, Stefan Reich wrote: > Hi there, > > I am currently using JavaSound on Oracle JDK 1.8 on Linux and Windows. > It's an unmitigated catastrophe. > > Something as simple as playing a Clip only works 60% of the time. The > other times, it just stays mute. > > This may not be your fault as I'm not currently using OpenJDK. How > different is the OpenJDK code base versus Oracle relating to JavaSound? > > Should I try OpenJDK again? > > The background is: I really want to support every end user out there, > so both OpenJDK and Oracle JDK should run my software well... > > I am working around the issue by actually invoking command line tools > (aplay on Linux, cmdmp3.exe on Windows) for playing sounds. Perfect? > Hell no. But JavaSound really is too thoroughly broken, at least on > Oracle JDK. > > Sorry for the harsh words. Where is the way out? > > All the best, > Stefan > > -- > Stefan Reich > BotCompany.de -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexey.menkov at oracle.com Thu Aug 17 16:48:31 2017 From: alexey.menkov at oracle.com (Alex Menkov) Date: Thu, 17 Aug 2017 09:48:31 -0700 Subject: [10] Review Request: 8181566 JavaSound javadoc clarification In-Reply-To: References: Message-ID: <837f8df5-da43-e204-904f-8aaf1ddf044d@oracle.com> Hi Sergey, I'm fine with this ("the same" (for 2nd case) looks more clear to me, but "identical" is also ok) --alex On 07/30/2017 16:07, Sergey Bylokhov wrote: > Hi, Alex. > Thank you for review! > I would like to propose and discuss other text: > > If the "equals()" method is overridden to not use "==": > > /** > * Indicates whether the specified object is equal to this info object, > * returning {@code true} if the objects are equal. > * > * @param obj the reference object with which to compare > * @return {@code true} the specified object is equal to this info > * object; {@code false} otherwise > */ > public final boolean equals(Object obj) { > > > And two versions if the "==" from Object is used: > > /** > * Indicates whether the specified object is equal to this info object, > * returning {@code true} if the objects are identical. > * > * @param obj the reference object with which to compare > * @return {@code true} the specified object is equal to this info > * object; {@code false} otherwise > */ > public final boolean equals(Object obj) { > > or: > > /** > * Indicates whether the specified object is equal to this info object, > * returning {@code true} if the objects are the same. > * > * @param obj the reference object with which to compare > * @return {@code true} the specified object is equal to this info > * object; {@code false} otherwise > */ > public final boolean equals(Object obj) { > > > In all versions the text in "@return " tag is short and the same. But description have different words about the objects: "identical"/"equal"/"the same". > > ps: The text for the current fix was copied from the Integer.java which I usually use when in doubts. > > ----- alexey.menkov at oracle.com wrote: > >> MidiSystem.java: >> >> @@ -1096,22 +1113,26 @@ >> return device; >> } >> } >> } >> >> - /* Provider class not specified or cannot be found, or >> - provider class specified, and no appropriate device available or >> - provider class and instance specified and instance cannot be found >> or >> is not appropriate */ >> + /* >> + * Provider class not specified or cannot be found, or provider >> class >> + * specified, and no appropriate device available or provider class >> and >> + * instance specified and instance cannot be found or is not >> appropriate >> + */ >> >> Old comment looks better (each "or" condition in a separate line) >> >> - /* No default are specified, or if something is specified, >> everything >> - failed. */ >> + /* >> + * No default are specified, or if something is specified, >> everything >> + * failed. >> + */ >> >> "No default is specified" or "No defaults are specified" >> >> >> AudioFileFormat.java: >> >> - * Finalizes the equals method. >> + * Indicates whether the specified object is equal to this >> file >> type, >> + * returning {@code true} if the objects are the same. >> + * >> + * @param obj the reference object with which to compare >> + * @return {@code true} if this file type is the same as the >> >> {@code obj} >> + * argument; {@code false} otherwise >> */ >> @Override >> public final boolean equals(final Object obj) { >> >> The implementation checks if the objects are equal, not that the >> objects >> are the same >> >> The same for AudioFormat.equals() >> >> (Note that in most cases equals() methods of JavaSound classes just >> call >> super.equals(), i.e. they really test is the objects are the same) >> >> --alex >> >> >> On 07/20/2017 18:46, Sergey Bylokhov wrote: >>> The DRAFT version of CSR was created: >>> https://bugs.openjdk.java.net/browse/JDK-8185020 >>> >>> ----- sergey.bylokhov at oracle.com wrote: >>>> >>>> The fix is updated: >>>> http://cr.openjdk.java.net/~serb/8181566/webrev.01 >>>> >>>>> I don't see the point of prettying up the docs on the un-used, >> commented out constants. >>>>> Can't we just delete them ? Seems like the decision was made >> years ago not to include them in the API >>>> >>> >>> It could be removed, but I still consider them as kind of todo, I >> hope >>> to check them one by one at some point. >>> From alexey.menkov at oracle.com Thu Aug 17 17:05:53 2017 From: alexey.menkov at oracle.com (Alex Menkov) Date: Thu, 17 Aug 2017 10:05:53 -0700 Subject: 8177951: Charset problem when the name of the sound device contains Chinese character. In-Reply-To: <58c0e291.53d6.15d9c7dae71.Coremail.cqjjjzr@126.com> References: <92fd9a29-de2e-4f1c-be12-5f5a4aae972f@default> <30d38b19.a924.15d60b1ab01.Coremail.cqjjjzr@126.com> <9004ea2e-7b50-1dae-3853-4f75cb44ba20@oracle.com> <1435cf32.29a.15d95a8349e.Coremail.cqjjjzr@126.com> <597E7B63.60409@oracle.com> <58c0e291.53d6.15d9c7dae71.Coremail.cqjjjzr@126.com> Message-ID: <97b2a3ac-e4cf-b596-8853-88d495534875@oracle.com> Hi Charlie, The fix looks good to me. Couple minor notes: - please replace tabs with 4 spaces in PLATFORM_API_WinOS_Charset_Util.cpp - could you add a comment for UnicodeToUTF8 function (in PLATFORM_API_WinOS_Charset_Util.h) specifying that it's a caller responsibility to free allocated memory by using delete[]) --alex On 07/31/2017 23:31, CharlieJiang wrote: > 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 " > # 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 > + > +#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 > + > +#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 > #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" 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 >>> # 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 >>> >>> 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 >>> # 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 >>> >>> 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 >>> + >>> +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 >>> + >>> +#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 >>> #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 >>> # 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 >>> >>> 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 >>> >>> -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" 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 >>>>> # 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 >>>>> >>>>> 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 >>>>> + >>>>> +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 >>>>> + >>>>> +#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 >>>>> #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 >>>>> + >>>>> +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 >>>>> + >>>>> +#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 >>>>> #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" 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 >>>>> >>>>> >>>>> ----- cqjjjzr at 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 >>>>>> >>>>> From Sergey.Bylokhov at oracle.com Fri Aug 18 23:35:47 2017 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Fri, 18 Aug 2017 16:35:47 -0700 Subject: JavaSound is not actually usable on Oracle JDK In-Reply-To: References: Message-ID: Hi, Stefan. Do you have a test example and an audio file which can reproduce the problem? If yes please file a bug to the bugs.java.com and send a bugid here. The bug can be related to the audio file format and/or to the audio formats supported by the test system. On 14.08.2017 6:24, Stefan Reich wrote: > Hi there, > > I am currently using JavaSound on Oracle JDK 1.8 on Linux and Windows. > It's an unmitigated catastrophe. > > Something as simple as playing a Clip only works 60% of the time. The > other times, it just stays mute. > > This may not be your fault as I'm not currently using OpenJDK. How > different is the OpenJDK code base versus Oracle relating to JavaSound? > > Should I try OpenJDK again? > > The background is: I really want to support every end user out there, so > both OpenJDK and Oracle JDK should run my software well... > > I am working around the issue by actually invoking command line tools > (aplay on Linux, cmdmp3.exe on Windows) for playing sounds. Perfect? > Hell no. But JavaSound really is too thoroughly broken, at least on > Oracle JDK. > > Sorry for the harsh words. Where is the way out? > > All the best, > Stefan > > -- > Stefan Reich > BotCompany.de -- Best regards, Sergey. From Sergey.Bylokhov at oracle.com Mon Aug 21 23:02:44 2017 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Mon, 21 Aug 2017 16:02:44 -0700 Subject: [10] Review Request: 8181566 JavaSound javadoc clarification In-Reply-To: <837f8df5-da43-e204-904f-8aaf1ddf044d@oracle.com> References: <837f8df5-da43-e204-904f-8aaf1ddf044d@oracle.com> Message-ID: <2d893136-0a02-0418-0d3b-fcaea2f6b1cb@oracle.com> Hi, Alex. Here is an updated webrev: http://cr.openjdk.java.net/~serb/8181566/webrev.03 The new CSR: https://bugs.openjdk.java.net/browse/JDK-8185020 On 17.08.2017 9:48, Alex Menkov wrote: > Hi Sergey, > > I'm fine with this ("the same" (for 2nd case) looks more clear to me, > but "identical" is also ok) > > --alex > > On 07/30/2017 16:07, Sergey Bylokhov wrote: >> Hi, Alex. >> Thank you for review! >> I would like to propose and discuss other text: >> >> If the "equals()" method is overridden to not use "==": >> >> ??? /** >> ???? * Indicates whether the specified object is equal to this info >> object, >> ???? * returning {@code true} if the objects are equal. >> ???? * >> ???? * @param? obj the reference object with which to compare >> ???? * @return {@code true} the specified object is equal to this info >> ???? *???????? object; {@code false} otherwise >> ???? */ >> ??? public final boolean equals(Object obj) { >> >> >> And two versions if the "==" from Object is used: >> >> ??? /** >> ???? * Indicates whether the specified object is equal to this info >> object, >> ???? * returning {@code true} if the objects are identical. >> ???? * >> ???? * @param? obj the reference object with which to compare >> ???? * @return {@code true} the specified object is equal to this info >> ???? *???????? object; {@code false} otherwise >> ???? */ >> ??? public final boolean equals(Object obj) { >> >> or: >> >> ??? /** >> ???? * Indicates whether the specified object is equal to this info >> object, >> ???? * returning {@code true} if the objects are the same. >> ???? * >> ???? * @param? obj the reference object with which to compare >> ???? * @return {@code true} the specified object is equal to this info >> ???? *???????? object; {@code false} otherwise >> ???? */ >> ??? public final boolean equals(Object obj) { >> >> >> In all versions the text in "@return " tag is short and the same. But >> description have different words about the objects: >> "identical"/"equal"/"the same". >> >> ps: The text for the current fix was copied from the Integer.java >> which I usually use when in doubts. >> >> ----- alexey.menkov at oracle.com wrote: >> >>> MidiSystem.java: >>> >>> @@ -1096,22 +1113,26 @@ >>> ????????????????????? return device; >>> ????????????????? } >>> ????????????? } >>> ????????? } >>> >>> - /* Provider class not specified or cannot be found, or >>> - provider class specified, and no appropriate device available or >>> - provider class and instance specified and instance cannot be found >>> or >>> is not appropriate */ >>> + /* >>> + * Provider class not specified or cannot be found, or provider >>> class >>> + * specified, and no appropriate device available or provider class >>> and >>> + * instance specified and instance cannot be found or is not >>> appropriate >>> + */ >>> >>> Old comment looks better (each "or" condition in a separate line) >>> >>> - /* No default are specified, or if something is specified, >>> everything >>> - failed. */ >>> + /* >>> + * No default are specified, or if something is specified, >>> everything >>> + * failed. >>> + */ >>> >>> "No default is specified" or "No defaults are specified" >>> >>> >>> AudioFileFormat.java: >>> >>> -???????? * Finalizes the equals method. >>> +???????? * Indicates whether the specified object is equal to this >>> file >>> type, >>> +???????? * returning {@code true} if the objects are the same. >>> +???????? * >>> +???????? * @param? obj the reference object with which to compare >>> +???????? * @return {@code true} if this file type is the same as the >>> >>> {@code obj} >>> +???????? *???????? argument; {@code false} otherwise >>> ?????????? */ >>> ????????? @Override >>> ????????? public final boolean equals(final Object obj) { >>> >>> The implementation checks if the objects are equal, not that the >>> objects >>> are the same >>> >>> The same for AudioFormat.equals() >>> >>> (Note that in most cases equals() methods of JavaSound classes just >>> call >>> super.equals(), i.e. they really test is the objects are the same) >>> >>> --alex >>> >>> >>> On 07/20/2017 18:46, Sergey Bylokhov wrote: >>>> The DRAFT version of CSR was created: >>>> https://bugs.openjdk.java.net/browse/JDK-8185020 >>>> >>>> ----- sergey.bylokhov at oracle.com wrote: >>>>> >>>>> The fix is updated: >>>>> http://cr.openjdk.java.net/~serb/8181566/webrev.01 >>>>> >>>>>> I don't see the point of prettying up the docs on the un-used, >>> commented out constants. >>>>>> Can't we just delete them ? Seems like the decision was made >>> years ago not to include them in the API >>>>> >>>> >>>> It could be removed, but I still consider them as kind of todo, I >>> hope >>>> to check them one by one at some point. >>>> -- Best regards, Sergey. From cqjjjzr at 126.com Tue Aug 22 01:12:07 2017 From: cqjjjzr at 126.com (CharlieJiang) Date: Tue, 22 Aug 2017 09:12:07 +0800 (CST) Subject: 8177951: Charset problem when the name of the sound device contains Chinese character. In-Reply-To: <97b2a3ac-e4cf-b596-8853-88d495534875@oracle.com> References: <92fd9a29-de2e-4f1c-be12-5f5a4aae972f@default> <30d38b19.a924.15d60b1ab01.Coremail.cqjjjzr@126.com> <9004ea2e-7b50-1dae-3853-4f75cb44ba20@oracle.com> <1435cf32.29a.15d95a8349e.Coremail.cqjjjzr@126.com> <597E7B63.60409@oracle.com> <58c0e291.53d6.15d9c7dae71.Coremail.cqjjjzr@126.com> <97b2a3ac-e4cf-b596-8853-88d495534875@oracle.com> Message-ID: <38a7688b.10e3.15e077f2843.Coremail.cqjjjzr@126.com> Hi Alex, So here it is: # HG changeset patch # User "CharlieJiang " # Date 1501568294 -28800 # Tue Aug 01 14:18:14 2017 +0800 # Node ID a99905b246d576e03eac6b8c66982fa7dc846477 # Parent 2425838cfb5e63bf798e383492890c25170b91d1 8177951: Charset problem when the name of the sound device contains Chinese character Contributed-by: Charlie Jiang 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 + +#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,44 @@ +/* + * 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 + +#ifdef __cplusplus +extern "C" { +#endif + +// NOTE: It's a caller responbility to free the allocated memory using delete[], just like in UnicodeToUTF8AndCopy function +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 #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; ==============EOF===EOF===EOF==================== ==============EOF===EOF===EOF==================== ==============EOF===EOF===EOF==================== ==============EOF===EOF===EOF==================== ==============EOF===EOF===EOF==================== At 2017-08-18 01:05:53, "Alex Menkov" wrote: >Hi Charlie, > >The fix looks good to me. >Couple minor notes: >- please replace tabs with 4 spaces in PLATFORM_API_WinOS_Charset_Util.cpp >- could you add a comment for UnicodeToUTF8 function (in >PLATFORM_API_WinOS_Charset_Util.h) specifying that it's a caller >responsibility to free allocated memory by using delete[]) > >--alex > >On 07/31/2017 23:31, CharlieJiang wrote: >> 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 " >> # 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 >> + >> +#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 >> + >> +#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 >> #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" 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 >>>> # 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 >>>> >>>> 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 >>>> # 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 >>>> >>>> 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 >>>> + >>>> +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 >>>> + >>>> +#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 >>>> #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 >>>> # 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 >>>> >>>> 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 >>>> >>>> -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" 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 From alexey.menkov at oracle.com Tue Aug 29 17:24:59 2017 From: alexey.menkov at oracle.com (Alex Menkov) Date: Tue, 29 Aug 2017 10:24:59 -0700 Subject: 8177951: Charset problem when the name of the sound device contains Chinese character. In-Reply-To: <37255a8a.1502.15e026b61e4.Coremail.cqjjjzr@126.com> References: <92fd9a29-de2e-4f1c-be12-5f5a4aae972f@default> <30d38b19.a924.15d60b1ab01.Coremail.cqjjjzr@126.com> <9004ea2e-7b50-1dae-3853-4f75cb44ba20@oracle.com> <1435cf32.29a.15d95a8349e.Coremail.cqjjjzr@126.com> <597E7B63.60409@oracle.com> <58c0e291.53d6.15d9c7dae71.Coremail.cqjjjzr@126.com> <97b2a3ac-e4cf-b596-8853-88d495534875@oracle.com> <37255a8a.1502.15e026b61e4.Coremail.cqjjjzr@126.com> Message-ID: <11d1f58d-67fc-fda7-c712-dfbd8c072dd8@oracle.com> Hi Charlie, The fix looks good to me. --alex On 08/20/2017 18:32, CharlieJiang wrote: > Hi Alex, > > So here it is: > > # HG changeset patch > # User "CharlieJiang " > # Date 1501568294 -28800 > # Tue Aug 01 14:18:14 2017 +0800 > # Node ID a99905b246d576e03eac6b8c66982fa7dc846477 > # Parent 2425838cfb5e63bf798e383492890c25170b91d1 > 8177951: Charset problem when the name of the sound device contains Chinese character > Contributed-by: Charlie Jiang > > 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 > + > +#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,44 @@ > +/* > + * 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 > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +// NOTE: It's a caller responbility to free the allocated memory using delete[], just like in UnicodeToUTF8AndCopy function > +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 > #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; > > ==============EOF===EOF===EOF==================== > ==============EOF===EOF===EOF==================== > ==============EOF===EOF===EOF==================== > ==============EOF===EOF===EOF==================== > ==============EOF===EOF===EOF==================== > > At 2017-08-18 01:05:53, "Alex Menkov" wrote: >> Hi Charlie, >> >> The fix looks good to me. >> Couple minor notes: >> - please replace tabs with 4 spaces in PLATFORM_API_WinOS_Charset_Util.cpp >> - could you add a comment for UnicodeToUTF8 function (in >> PLATFORM_API_WinOS_Charset_Util.h) specifying that it's a caller >> responsibility to free allocated memory by using delete[]) >> >> --alex >> >> On 07/31/2017 23:31, CharlieJiang wrote: >>> 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 " >>> # 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 >>> + >>> +#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 >>> + >>> +#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 >>> #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" 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 >>>>> # 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 >>>>> >>>>> 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 >>>>> # 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 >>>>> >>>>> 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 >>>>> + >>>>> +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 >>>>> + >>>>> +#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 >>>>> #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 >>>>> # 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 >>>>> >>>>> 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 >>>>> >>>>> -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" 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 >>>>>>> # 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 >>>>>>> >>>>>>> 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 >>>>>>> + >>>>>>> +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 >>>>>>> + >>>>>>> +#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 >>>>>>> #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 >>>>>>> + >>>>>>> +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 >>>>>>> + >>>>>>> +#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 >>>>>>> #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" 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 >>>>>>> >>>>>>> >>>>>>> ----- cqjjjzr at 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 >>>>>>>> >>>>>>> From sergey.bylokhov at oracle.com Tue Aug 29 20:52:05 2017 From: sergey.bylokhov at oracle.com (Sergey Bylokhov) Date: Tue, 29 Aug 2017 13:52:05 -0700 (PDT) Subject: 8177951: Charset problem when the name of the sound device contains Chinese character. Message-ID: I'll sponsor the fix and push it soon. ----- alexey.menkov at oracle.com wrote: > Hi Charlie, > > The fix looks good to me. > > --alex > > On 08/20/2017 18:32, CharlieJiang wrote: > > Hi Alex, > > > > So here it is: > > > > # HG changeset patch > > # User "CharlieJiang " > > # Date 1501568294 -28800 > > # Tue Aug 01 14:18:14 2017 +0800 > > # Node ID a99905b246d576e03eac6b8c66982fa7dc846477 > > # Parent 2425838cfb5e63bf798e383492890c25170b91d1 > > 8177951: Charset problem when the name of the sound device contains > Chinese character > > Contributed-by: Charlie Jiang > > > > 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 > > + > > +#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,44 @@ > > +/* > > + * 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 > > + > > +#ifdef __cplusplus > > +extern "C" { > > +#endif > > + > > +// NOTE: It's a caller responbility to free the allocated memory > using delete[], just like in UnicodeToUTF8AndCopy function > > +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 > > #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; > > > > ==============EOF===EOF===EOF==================== > > ==============EOF===EOF===EOF==================== > > ==============EOF===EOF===EOF==================== > > ==============EOF===EOF===EOF==================== > > ==============EOF===EOF===EOF==================== > > > > At 2017-08-18 01:05:53, "Alex Menkov" > wrote: > >> Hi Charlie, > >> > >> The fix looks good to me. > >> Couple minor notes: > >> - please replace tabs with 4 spaces in > PLATFORM_API_WinOS_Charset_Util.cpp > >> - could you add a comment for UnicodeToUTF8 function (in > >> PLATFORM_API_WinOS_Charset_Util.h) specifying that it's a caller > >> responsibility to free allocated memory by using delete[]) > >> > >> --alex > >> > >> On 07/31/2017 23:31, CharlieJiang wrote: > >>> 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 " > >>> # 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 > >>> + > >>> +#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 > >>> + > >>> +#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 > >>> #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" > 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 > >>>>> # 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 > >>>>> > >>>>> 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 > >>>>> # 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 > >>>>> > >>>>> 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 > >>>>> + > >>>>> +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 > >>>>> + > >>>>> +#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 > >>>>> #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 > >>>>> # 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 > >>>>> > >>>>> 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 > >>>>> > >>>>> -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" > 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 > >>>>>>> # 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 > >>>>>>> > >>>>>>> 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 > >>>>>>> + > >>>>>>> +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 > >>>>>>> + > >>>>>>> +#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 > >>>>>>> #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 > >>>>>>> + > >>>>>>> +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 > >>>>>>> + > >>>>>>> +#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 > >>>>>>> #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" 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 > >>>>>>> > >>>>>>> > >>>>>>> ----- cqjjjzr at 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 > >>>>>>>> > >>>>>>> From alexey.menkov at oracle.com Tue Aug 29 20:57:10 2017 From: alexey.menkov at oracle.com (Alex Menkov) Date: Tue, 29 Aug 2017 13:57:10 -0700 Subject: [10] Review Request: 8181566 JavaSound javadoc clarification In-Reply-To: <2d893136-0a02-0418-0d3b-fcaea2f6b1cb@oracle.com> References: <837f8df5-da43-e204-904f-8aaf1ddf044d@oracle.com> <2d893136-0a02-0418-0d3b-fcaea2f6b1cb@oracle.com> Message-ID: <97980913-3850-d72b-5654-1deff802da98@oracle.com> The fix looks good. I've added myself as a reviewer at the CSR. --alex On 08/21/2017 16:02, Sergey Bylokhov wrote: > Hi, Alex. > Here is an updated webrev: > http://cr.openjdk.java.net/~serb/8181566/webrev.03 > > The new CSR: > https://bugs.openjdk.java.net/browse/JDK-8185020 > > On 17.08.2017 9:48, Alex Menkov wrote: >> Hi Sergey, >> >> I'm fine with this ("the same" (for 2nd case) looks more clear to me, >> but "identical" is also ok) >> >> --alex >> >> On 07/30/2017 16:07, Sergey Bylokhov wrote: >>> Hi, Alex. >>> Thank you for review! >>> I would like to propose and discuss other text: >>> >>> If the "equals()" method is overridden to not use "==": >>> >>> /** >>> * Indicates whether the specified object is equal to this info >>> object, >>> * returning {@code true} if the objects are equal. >>> * >>> * @param obj the reference object with which to compare >>> * @return {@code true} the specified object is equal to this info >>> * object; {@code false} otherwise >>> */ >>> public final boolean equals(Object obj) { >>> >>> >>> And two versions if the "==" from Object is used: >>> >>> /** >>> * Indicates whether the specified object is equal to this info >>> object, >>> * returning {@code true} if the objects are identical. >>> * >>> * @param obj the reference object with which to compare >>> * @return {@code true} the specified object is equal to this info >>> * object; {@code false} otherwise >>> */ >>> public final boolean equals(Object obj) { >>> >>> or: >>> >>> /** >>> * Indicates whether the specified object is equal to this info >>> object, >>> * returning {@code true} if the objects are the same. >>> * >>> * @param obj the reference object with which to compare >>> * @return {@code true} the specified object is equal to this info >>> * object; {@code false} otherwise >>> */ >>> public final boolean equals(Object obj) { >>> >>> >>> In all versions the text in "@return " tag is short and the same. But >>> description have different words about the objects: >>> "identical"/"equal"/"the same". >>> >>> ps: The text for the current fix was copied from the Integer.java >>> which I usually use when in doubts. >>> >>> ----- alexey.menkov at oracle.com wrote: >>> >>>> MidiSystem.java: >>>> >>>> @@ -1096,22 +1113,26 @@ >>>> return device; >>>> } >>>> } >>>> } >>>> >>>> - /* Provider class not specified or cannot be found, or >>>> - provider class specified, and no appropriate device available or >>>> - provider class and instance specified and instance cannot be found >>>> or >>>> is not appropriate */ >>>> + /* >>>> + * Provider class not specified or cannot be found, or provider >>>> class >>>> + * specified, and no appropriate device available or provider class >>>> and >>>> + * instance specified and instance cannot be found or is not >>>> appropriate >>>> + */ >>>> >>>> Old comment looks better (each "or" condition in a separate line) >>>> >>>> - /* No default are specified, or if something is specified, >>>> everything >>>> - failed. */ >>>> + /* >>>> + * No default are specified, or if something is specified, >>>> everything >>>> + * failed. >>>> + */ >>>> >>>> "No default is specified" or "No defaults are specified" >>>> >>>> >>>> AudioFileFormat.java: >>>> >>>> - * Finalizes the equals method. >>>> + * Indicates whether the specified object is equal to this >>>> file >>>> type, >>>> + * returning {@code true} if the objects are the same. >>>> + * >>>> + * @param obj the reference object with which to compare >>>> + * @return {@code true} if this file type is the same as the >>>> >>>> {@code obj} >>>> + * argument; {@code false} otherwise >>>> */ >>>> @Override >>>> public final boolean equals(final Object obj) { >>>> >>>> The implementation checks if the objects are equal, not that the >>>> objects >>>> are the same >>>> >>>> The same for AudioFormat.equals() >>>> >>>> (Note that in most cases equals() methods of JavaSound classes just >>>> call >>>> super.equals(), i.e. they really test is the objects are the same) >>>> >>>> --alex >>>> >>>> >>>> On 07/20/2017 18:46, Sergey Bylokhov wrote: >>>>> The DRAFT version of CSR was created: >>>>> https://bugs.openjdk.java.net/browse/JDK-8185020 >>>>> >>>>> ----- sergey.bylokhov at oracle.com wrote: >>>>>> >>>>>> The fix is updated: >>>>>> http://cr.openjdk.java.net/~serb/8181566/webrev.01 >>>>>> >>>>>>> I don't see the point of prettying up the docs on the un-used, >>>> commented out constants. >>>>>>> Can't we just delete them ? Seems like the decision was made >>>> years ago not to include them in the API >>>>>> >>>>> >>>>> It could be removed, but I still consider them as kind of todo, I >>>> hope >>>>> to check them one by one at some point. >>>>> > >