Hi Sergey,

I finished writing the new patch according to your suggestions.
I wrote a new source file and a header file to handle the charset problem. 
And I fixed this problem in all Direct devices, Ports and MIDI devices.
But I don't have debugging environment of MIDI devices. 
So it will be very nice if somebody can test MIDI devices for me.
here's the new patch, the parent changeset is the previous patch(the 
direct-devices only commit):


# HG changeset patch
# User Charlie Jiang<cqjj...@126.com>
# Date 1500538314 -28800
# Node ID c86ae2f3e1022f9b27ad6918fa342c5a4ee309c0
# Parent  1bfe64cffda51c00fccf48e9c0c2adb533fa7e5c
8177951: Charset problem when the name of the sound device contains Chinese 
character
Summary: Fix issues in the ANSI2UTF-8 function and move it to a seperate file 
and fix Port Sound and MIDI Sound devices.
Contributed-by: Charlie Jiang <cqjj...@126.com>

diff --git a/make/lib/SoundLibraries.gmk b/make/lib/SoundLibraries.gmk
--- a/make/lib/SoundLibraries.gmk
+++ b/make/lib/SoundLibraries.gmk
@@ -61,6 +61,7 @@
       -DUSE_PLATFORM_MIDI_IN=TRUE \
       -DUSE_PORTS=TRUE
   LIBJSOUND_SRC_FILES += \
+      PLATFORM_API_WinOS_Charset_Util.cpp \
       PLATFORM_API_WinOS_MidiIn.cpp \
       PLATFORM_API_WinOS_MidiOut.c \
       PLATFORM_API_WinOS_Util.c \
@@ -190,6 +191,7 @@
       OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
       SRC := $(LIBJSOUND_SRC_DIRS), \
       INCLUDE_FILES := Utilities.c $(LIBJSOUND_DAUDIOFILES) \
+          PLATFORM_API_WinOS_Charset_Util.cpp \
           PLATFORM_API_WinOS_DirectSound.cpp, \
       OPTIMIZATION := LOW, \
       CFLAGS := $(CFLAGS_JDKLIB) \
diff --git 
a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp 
b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp
new file mode 100644
--- /dev/null
+++ 
b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+ 
+#include "PLATFORM_API_WinOS_Charset_Util.h"
+
+#include <cstring>
+
+extern "C" LPSTR ANSIToUTF8(const LPCSTR lpAnsiStr)
+{    
+    // ANSI -> Unicode
+    DWORD dwUnicodeLen = 0;
+    LPWSTR lpUnicodeStr = nullptr;
+    dwUnicodeLen = MultiByteToWideChar(CP_ACP, 0, lpAnsiStr, -1, nullptr, 0);
+    lpUnicodeStr = new WCHAR[dwUnicodeLen];
+    memset(lpUnicodeStr, 0, (dwUnicodeLen) * sizeof(WCHAR));
+    MultiByteToWideChar(CP_ACP, 0, lpAnsiStr, -1, lpUnicodeStr, dwUnicodeLen);
+
+    // Unicode -> UTF8
+    LPSTR lpUTF8Str = nullptr;
+    DWORD dwUTF8Len = 0;
+    dwUTF8Len = WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, nullptr, 0, 
nullptr, nullptr);
+    lpUTF8Str = new CHAR[dwUTF8Len];
+    memset(lpUTF8Str, 0, sizeof(CHAR) * (dwUTF8Len));
+    WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, lpUTF8Str, dwUTF8Len, 
nullptr, nullptr);
+    delete[] lpUnicodeStr;
+    return lpUTF8Str;
+}
+
+extern "C" void ANSIToUTF8IfNeededAndCopy(LPSTR dest, LPCSTR src, SIZE_T 
maxLength) {
+#ifndef UNICODE
+    LPSTR utf8EncodedName = ANSIToUTF8(src);
+    strncpy(dest, utf8EncodedName, maxLength - 1);
+    delete[] utf8EncodedName;
+#else
+    strncpy(dest, src, maxLength - 1);
+#endif
+    dest[maxLength - 1] = '\0';
+}
+ 
\ No newline at end of file
diff --git 
a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.h 
b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.h
new file mode 100644
--- /dev/null
+++ 
b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef PLATFORM_API_WINOS_CHARSET_UTILS_H
+#define PLATFORM_API_WINOS_CHARSET_UTILS_H
+
+#include <windows.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LPSTR _cdecl ANSIToUTF8(const LPCSTR lpAnsiStr);
+
+void _cdecl ANSIToUTF8IfNeededAndCopy(LPSTR dest, LPCSTR src, SIZE_T 
maxLength);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git 
a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp 
b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp
--- 
a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp
+++ 
b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp
@@ -52,6 +52,9 @@
 }
 #endif
 
+/* include to prevent charset problem */
+#include "PLATFORM_API_WinOS_Charset_Util.h"
+
 #ifdef USE_DEBUG_SILENCING
 #define DEBUG_SILENCING0(p) TRACE0(p)
 #define DEBUG_SILENCING1(p1,p2) TRACE1(p1,p2)
@@ -86,28 +89,6 @@
 static UINT64 g_lastCacheRefreshTime = 0;
 static INT32 g_mixerCount = 0;
 
-/// FIX BUG JDK-8177951: Convert ANSI encoded string to UTF-8 encoded string
-LPCSTR ANSIToUTF8(const LPCSTR& lpAnsiStr)
-{
-    // ANSI -> Unicode
-    DWORD dwAnsiLen = strlen(lpAnsiStr);
-    DWORD dwUnicodeLen = ::MultiByteToWideChar(CP_ACP, 0, lpAnsiStr, -1, NULL, 
0);
-    LPWSTR lpUnicodeStr;
-    lpUnicodeStr = new WCHAR[dwUnicodeLen];
-    memset(lpUnicodeStr, 0, (dwUnicodeLen) * sizeof(WCHAR));
-    MultiByteToWideChar(CP_ACP, 0, lpAnsiStr, -1, lpUnicodeStr, dwUnicodeLen);
-
-    // Unicode -> UTF8
-    LPSTR lpUTF8Str;
-    DWORD dwUTF8Len;
-    dwUTF8Len = WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, NULL, 0, 
NULL, NULL);
-    lpUTF8Str = new CHAR[dwUTF8Len];
-    memset(lpUTF8Str, 0, sizeof(CHAR) * (dwUTF8Len));
-    WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, lpUTF8Str, dwUTF8Len, 
NULL, NULL);
-    delete lpUnicodeStr;
-    return lpUTF8Str;
-}
-
 BOOL DS_lockCache() {
     /* dummy implementation for now, Java does locking */
     return TRUE;
@@ -255,13 +236,7 @@
 
     INT32 cacheIndex = findCacheItemByGUID(lpGuid, 
g_audioDeviceCache[desc->deviceID].isSource);
     if (cacheIndex == desc->deviceID) {
-#ifndef UNICODE
-        LPCSTR utf8EncodedName = ANSIToUTF8(lpstrDescription);
-        strncpy(desc->name, utf8EncodedName, DAUDIO_STRING_LENGTH);
-        delete utf8EncodedName;
-#else
-        strncpy(desc->name, lpstrDescription, DAUDIO_STRING_LENGTH);
-#endif
+        ANSIToUTF8IfNeededAndCopy(desc->name, lpstrDescription, 
DAUDIO_STRING_LENGTH);
         //strncpy(desc->description, lpstrModule, DAUDIO_STRING_LENGTH);
         desc->maxSimulLines = -1;
         /* do not continue enumeration */
diff --git 
a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp 
b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp
--- a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp
+++ b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp
@@ -31,6 +31,9 @@
 #include "PLATFORM_API_WinOS_Util.h"
 }
 
+/* include to prevent charset problem */
+#include "PLATFORM_API_WinOS_Charset_Util.h"
+
 #if USE_PLATFORM_MIDI_IN == TRUE
 
 #ifdef USE_ERROR
@@ -258,8 +261,7 @@
     INT32 err;
 
     if (getMidiInCaps(deviceID, &midiInCaps, &err)) {
-        strncpy(name, midiInCaps.szPname, nameLength-1);
-        name[nameLength-1] = 0;
+        ANSIToUTF8IfNeededAndCopy(name, midiInCaps.szPname, nameLength);
         return MIDI_SUCCESS;
     }
     MIDIIN_CHECK_ERROR;
diff --git 
a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c 
b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c
--- a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c
+++ b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c
@@ -28,6 +28,9 @@
 
 #include "PLATFORM_API_WinOS_Util.h"
 
+/* include to prevent charset problem */
+#include "PLATFORM_API_WinOS_Charset_Util.h"
+
 #if USE_PLATFORM_MIDI_OUT == TRUE
 
 
@@ -82,8 +85,7 @@
     INT32 err;
 
     if (getMidiOutCaps(deviceID, &midiOutCaps, &err)) {
-        strncpy(name, midiOutCaps.szPname, nameLength-1);
-        name[nameLength-1] = 0;
+        ANSIToUTF8IfNeededAndCopy(name, midiOutCaps.szPname, nameLength);
         return MIDI_SUCCESS;
     }
     MIDIOUT_CHECK_ERROR;
diff --git 
a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c 
b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c
--- a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c
+++ b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c
@@ -38,6 +38,9 @@
 #include <mmsystem.h>
 #include "Ports.h"
 
+/* include to prevent charset problem */
+#include "PLATFORM_API_WinOS_Charset_Util.h"
+
 #if USE_PORTS == TRUE
 
 typedef struct tag_PortControlID PortControlID;
@@ -355,8 +358,7 @@
 INT32 PORT_GetPortMixerDescription(INT32 mixerIndex, PortMixerDescription* 
description) {
     MIXERCAPS mixerCaps;
     if (mixerGetDevCaps(mixerIndex, &mixerCaps, sizeof(MIXERCAPS)) == 
MMSYSERR_NOERROR) {
-        strncpy(description->name, mixerCaps.szPname, PORT_STRING_LENGTH-1);
-        description->name[PORT_STRING_LENGTH-1] = 0;
+        ANSIToUTF8IfNeededAndCopy(description->name, mixerCaps.szPname, 
PORT_STRING_LENGTH);
         sprintf(description->version, "%d.%d", (mixerCaps.vDriverVersion & 
0xFF00) >> 8, mixerCaps.vDriverVersion & 0xFF);
         strncpy(description->description, "Port Mixer", PORT_STRING_LENGTH-1);
         return TRUE;


===================================================================================================
=================================EOF===============================================================
===================================================================================================


And if you need a patch that can be directly applied to the root repo, then use 
this:


diff --git a/make/lib/SoundLibraries.gmk b/make/lib/SoundLibraries.gmk
--- a/make/lib/SoundLibraries.gmk
+++ b/make/lib/SoundLibraries.gmk
@@ -61,6 +61,7 @@
       -DUSE_PLATFORM_MIDI_IN=TRUE \
       -DUSE_PORTS=TRUE
   LIBJSOUND_SRC_FILES += \
+      PLATFORM_API_WinOS_Charset_Util.cpp \
       PLATFORM_API_WinOS_MidiIn.cpp \
       PLATFORM_API_WinOS_MidiOut.c \
       PLATFORM_API_WinOS_Util.c \
@@ -190,6 +191,7 @@
       OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
       SRC := $(LIBJSOUND_SRC_DIRS), \
       INCLUDE_FILES := Utilities.c $(LIBJSOUND_DAUDIOFILES) \
+          PLATFORM_API_WinOS_Charset_Util.cpp \
           PLATFORM_API_WinOS_DirectSound.cpp, \
       OPTIMIZATION := LOW, \
       CFLAGS := $(CFLAGS_JDKLIB) \
diff --git 
a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp 
b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp
new file mode 100644
--- /dev/null
+++ 
b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+ 
+#include "PLATFORM_API_WinOS_Charset_Util.h"
+
+#include <cstring>
+
+extern "C" LPSTR ANSIToUTF8(const LPCSTR lpAnsiStr)
+{    
+    // ANSI -> Unicode
+    DWORD dwUnicodeLen = 0;
+    LPWSTR lpUnicodeStr = nullptr;
+    dwUnicodeLen = MultiByteToWideChar(CP_ACP, 0, lpAnsiStr, -1, nullptr, 0);
+    lpUnicodeStr = new WCHAR[dwUnicodeLen];
+    memset(lpUnicodeStr, 0, (dwUnicodeLen) * sizeof(WCHAR));
+    MultiByteToWideChar(CP_ACP, 0, lpAnsiStr, -1, lpUnicodeStr, dwUnicodeLen);
+
+    // Unicode -> UTF8
+    LPSTR lpUTF8Str = nullptr;
+    DWORD dwUTF8Len = 0;
+    dwUTF8Len = WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, nullptr, 0, 
nullptr, nullptr);
+    lpUTF8Str = new CHAR[dwUTF8Len];
+    memset(lpUTF8Str, 0, sizeof(CHAR) * (dwUTF8Len));
+    WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, lpUTF8Str, dwUTF8Len, 
nullptr, nullptr);
+    delete[] lpUnicodeStr;
+    return lpUTF8Str;
+}
+
+extern "C" void ANSIToUTF8IfNeededAndCopy(LPSTR dest, LPCSTR src, SIZE_T 
maxLength) {
+#ifndef UNICODE
+    LPSTR utf8EncodedName = ANSIToUTF8(src);
+    strncpy(dest, utf8EncodedName, maxLength - 1);
+    delete[] utf8EncodedName;
+#else
+    strncpy(dest, src, maxLength - 1);
+#endif
+    dest[maxLength - 1] = '\0';
+}
+ 
\ No newline at end of file
diff --git 
a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.h 
b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.h
new file mode 100644
--- /dev/null
+++ 
b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Charset_Util.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef PLATFORM_API_WINOS_CHARSET_UTILS_H
+#define PLATFORM_API_WINOS_CHARSET_UTILS_H
+
+#include <windows.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LPSTR _cdecl ANSIToUTF8(const LPCSTR lpAnsiStr);
+
+void _cdecl ANSIToUTF8IfNeededAndCopy(LPSTR dest, LPCSTR src, SIZE_T 
maxLength);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git 
a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp 
b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp
--- 
a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp
+++ 
b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp
@@ -52,6 +52,9 @@
 }
 #endif
 
+/* include to prevent charset problem */
+#include "PLATFORM_API_WinOS_Charset_Util.h"
+
 #ifdef USE_DEBUG_SILENCING
 #define DEBUG_SILENCING0(p) TRACE0(p)
 #define DEBUG_SILENCING1(p1,p2) TRACE1(p1,p2)
@@ -233,7 +236,7 @@
 
     INT32 cacheIndex = findCacheItemByGUID(lpGuid, 
g_audioDeviceCache[desc->deviceID].isSource);
     if (cacheIndex == desc->deviceID) {
-        strncpy(desc->name, lpstrDescription, DAUDIO_STRING_LENGTH);
+        ANSIToUTF8IfNeededAndCopy(desc->name, lpstrDescription, 
DAUDIO_STRING_LENGTH);
         //strncpy(desc->description, lpstrModule, DAUDIO_STRING_LENGTH);
         desc->maxSimulLines = -1;
         /* do not continue enumeration */
diff --git 
a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp 
b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp
--- a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp
+++ b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiIn.cpp
@@ -31,6 +31,9 @@
 #include "PLATFORM_API_WinOS_Util.h"
 }
 
+/* include to prevent charset problem */
+#include "PLATFORM_API_WinOS_Charset_Util.h"
+
 #if USE_PLATFORM_MIDI_IN == TRUE
 
 #ifdef USE_ERROR
@@ -258,8 +261,7 @@
     INT32 err;
 
     if (getMidiInCaps(deviceID, &midiInCaps, &err)) {
-        strncpy(name, midiInCaps.szPname, nameLength-1);
-        name[nameLength-1] = 0;
+        ANSIToUTF8IfNeededAndCopy(name, midiInCaps.szPname, nameLength);
         return MIDI_SUCCESS;
     }
     MIDIIN_CHECK_ERROR;
diff --git 
a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c 
b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c
--- a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c
+++ b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_MidiOut.c
@@ -28,6 +28,9 @@
 
 #include "PLATFORM_API_WinOS_Util.h"
 
+/* include to prevent charset problem */
+#include "PLATFORM_API_WinOS_Charset_Util.h"
+
 #if USE_PLATFORM_MIDI_OUT == TRUE
 
 
@@ -82,8 +85,7 @@
     INT32 err;
 
     if (getMidiOutCaps(deviceID, &midiOutCaps, &err)) {
-        strncpy(name, midiOutCaps.szPname, nameLength-1);
-        name[nameLength-1] = 0;
+        ANSIToUTF8IfNeededAndCopy(name, midiOutCaps.szPname, nameLength);
         return MIDI_SUCCESS;
     }
     MIDIOUT_CHECK_ERROR;
diff --git 
a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c 
b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c
--- a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c
+++ b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_Ports.c
@@ -38,6 +38,9 @@
 #include <mmsystem.h>
 #include "Ports.h"
 
+/* include to prevent charset problem */
+#include "PLATFORM_API_WinOS_Charset_Util.h"
+
 #if USE_PORTS == TRUE
 
 typedef struct tag_PortControlID PortControlID;
@@ -355,8 +358,7 @@
 INT32 PORT_GetPortMixerDescription(INT32 mixerIndex, PortMixerDescription* 
description) {
     MIXERCAPS mixerCaps;
     if (mixerGetDevCaps(mixerIndex, &mixerCaps, sizeof(MIXERCAPS)) == 
MMSYSERR_NOERROR) {
-        strncpy(description->name, mixerCaps.szPname, PORT_STRING_LENGTH-1);
-        description->name[PORT_STRING_LENGTH-1] = 0;
+        ANSIToUTF8IfNeededAndCopy(description->name, mixerCaps.szPname, 
PORT_STRING_LENGTH);
         sprintf(description->version, "%d.%d", (mixerCaps.vDriverVersion & 
0xFF00) >> 8, mixerCaps.vDriverVersion & 0xFF);
         strncpy(description->description, "Port Mixer", PORT_STRING_LENGTH-1);
         return TRUE;


About the issue of the OCA, because actually I won't often push code to the 
OpenJDK repo, 
so I think it's unnecessary to join the OCB now, and the steps to join it is 
pretty complex.

Cheers,
Charlie Jiang
2017-7-20

PS: a picture of the effect of the new patch:
http://imgur.com/a/SjlAU

===================================================================================================
=================================EOF===============================================================
===================================================================================================


At 2017-07-18 08:38:15, "Sergey Bylokhov" <sergey.bylok...@oracle.com> wrote:
 
p { margin: 0; }
Hello.
I uploaded the current patch to cr.openjdk:
http://cr.openjdk.java.net/~serb/8177951/webrev.00

I have tested the patch and here is my observation:
 - The patch works for direct devices, but it looks like the same bug exists in 
Ports(also reproduced by your testcase), did you have a chance to look into 
this issue as well?
 - jdk uses "warning-as-error" policy during the build, so currently there is a 
build failure, because of this warning:
        PLATFORM_API_WinOS_DirectSound.cpp(93) : warning C4267: 'initializing' 
: conversion from 'size_t' to 'DWORD', possible loss of data
 - Note that the memory which is allocated by "new[]" should be deallocated by 
the "delete[]", but current fix use simple "delete".
 - Can you please sign and submit the OCA[1], which will allow you to 
contribute to the openjdk?

[1] http://www.oracle.com/technetwork/community/oca-486395.html


----- cqjj...@126.com wrote:

> 
> 
Hello,
Please review this bug report: https://bugs.openjdk.java.net/browse/JDK-8177951 

> 
A brief description of the issue:
In non-English Windows, the DirectAudioDeviceProvider can't work properly, 
AudioSystem.getMixerInfo()[0].getName() (or any other index, as long as the 
name of mixer contains non-ASCII characters)will return a corrupted string (all 
non-ASCII chars become messy codes).
The main reason is in native codes, we get a string in ANSI(platform-dependent) 
charset. But in the code the string is just processed as a UTF-8 string. So the 
JVM encodes ANSI string by UTF-8 encoding.

> 
Detailed description:
The performace of the bug is contained in the link above, I'll talk about the 
reason of the issue. All research below are based on OpenJDK 9, but I think 
OpenJDK 8 is also applicable.

> 
In 
jdk/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp,
 Function DS_GetDesc_Enum, Line 236, the name of the device is gotten(called by 
function DirectSoundDeviceEnumerate) from the OS, in ANSI charset, in a LPCSTR. 
And you just copy the ANSI encoded string to the DirectAudioDeviceDescription 
struct. So let's look at the 
jdk/src/java.desktop/share/native/libjsound/DirectAudioDeviceProvider.c, 
Function getDirectAudioDeviceDescription and 
Java_com_sun_media_sound_DirectAudioDeviceProvider_nNewDirectAudioDeviceInfo, 
Line 48 and 98, you called NewStringUTF function with a ANSI encoded string. So 
we got a UTF-8 encoded ANSI string. But obviously we need a UTF-8 encoded 
Unicode String.

> 
I wrote to Oracle but they can't reproduce the issue, so I went on fixing the 
bug by myself. I wrote a function to convert ANSI string to UTF-8 encoded 
Unicode string.

> 
And I found a problem: In Multi-Byte compiling mode, DirectSoundDeviceEnumerate 
will call DirectSoundDeviceEnumerateA and it will present a ANSI string as the 
argument, but in Unicode mode, DirectSoundDeviceEnumerate calls 
DirectSoundDeviceEnumerateW which presents a UTF-8 encoded Unicode string! So I 
think it's necessary to check if the compiler is in Unicode mode(by checking 
UNICODE macro), and only convert the string when it's in Multi-Byte mode.

> 
But, I don't have the debugging environment, I have problem configuring the 
compiler of OpenJDK. LINK : error LNK2001: unresolved external symbol 
_mainCRTStartup when executing ./configure script. So I can't test the 
validness of the patch. I'll be grateful if someone can help solve the 
configuring problem or test the patch for me. Even if you can compile the JDK 
with the patch is OK.
If you'd like to test the patch, you can test it with the first device from 
DirectSoundDeviceEnumerate, 'Primary Sound Driver'. Maybe you don't have 
Chinese font, I'll attach a picture to the correct output.

> 
The patch is below and attached with the E-Mail. It's applicable for OpenJDK9, 
maybe 8 if you change it.
https://imgur.com/a/6kgeU 
The code in the picture is just for generate a output, in the Unicode mode, so 
it's not applicable for JDK.

> 

*** 
old/jdk/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp
        2017-06-21 03:57:42.000000000 +0800
--- 
new/jdk/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp
        2017-06-24 16:26:57.232247800 +0800
***************
*** 86,91 ****
--- 86,113 ----
  static UINT64 g_lastCacheRefreshTime = 0;
  static INT32 g_mixerCount = 0;
  
+ /// FIX BUG JDK-8177951: Convert ANSI encoded string to UTF-8 encoded string
+ LPCSTR ANSIToUTF8(const LPCSTR& lpAnsiStr)
+ {
+     // ANSI -> Unicode
+     DWORD dwAnsiLen = strlen(lpAnsiStr);
+     DWORD dwUnicodeLen = ::MultiByteToWideChar(CP_ACP, 0, lpAnsiStr, -1, 
NULL, 0);
+     LPWSTR lpUnicodeStr;
+     lpUnicodeStr = new WCHAR[dwUnicodeLen];
+     memset(lpUnicodeStr, 0, (dwUnicodeLen) * sizeof(WCHAR));
+     MultiByteToWideChar(CP_ACP, 0, lpAnsiStr, -1, lpUnicodeStr, dwUnicodeLen);
+ 
+     // Unicode -> UTF8
+     LPSTR lpUTF8Str;
+     DWORD dwUTF8Len;
+     dwUTF8Len = WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, NULL, 0, 
NULL, NULL);
+     lpUTF8Str = new CHAR[dwUTF8Len];
+     memset(lpUTF8Str, 0, sizeof(CHAR) * (dwUTF8Len));
+     WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, lpUTF8Str, dwUTF8Len, 
NULL, NULL);
+     delete lpUnicodeStr;
+     return lpUTF8Str;
+ }
+ 
  BOOL DS_lockCache() {
      /* dummy implementation for now, Java does locking */
      return TRUE;
***************
*** 233,239 ****
--- 255,267 ----
  
      INT32 cacheIndex = findCacheItemByGUID(lpGuid, 
g_audioDeviceCache[desc->deviceID].isSource);
      if (cacheIndex == desc->deviceID) {
+ #ifndef UNICODE
+         LPCSTR utf8EncodedName = ANSIToUTF8(lpstrDescription);
+         strncpy(desc->name, utf8EncodedName, DAUDIO_STRING_LENGTH);
+         delete utf8EncodedName;
+ #else
          strncpy(desc->name, lpstrDescription, DAUDIO_STRING_LENGTH);
+ #endif
          //strncpy(desc->description, lpstrModule, DAUDIO_STRING_LENGTH);
          desc->maxSimulLines = -1;
          /* do not continue enumeration */

> 

> 
Cheers,
Charlie Jiang
> 
> 
 

Reply via email to