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