From f93987b45509562f4901e736e7fae5676bb09596 Mon Sep 17 00:00:00 2001 From: overpathz Date: Thu, 1 Dec 2022 22:45:15 +0200 Subject: [PATCH] Provide multilingual support of Kernel32Util.formatMessage() --- .../sun/jna/platform/win32/Kernel32Util.java | 27 ++++++++++++++++--- .../jna/platform/win32/Kernel32UtilTest.java | 12 +++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java index 9654fc52b1..324da008bc 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java @@ -178,14 +178,35 @@ public static void closeHandle(HANDLE h) { } } + /** + * Format a message from a code. + * + * @param code The error code + * @return Formatted message in the default locale. + */ + public static String formatMessage(int code) { + return formatMessage(code, 0, 0); + } + /** * Format a message from the value obtained from * {@link Kernel32#GetLastError()} or {@link Native#getLastError()}. * + *

If you pass in zero, FormatMessage looks for a message for LANGIDs in the following order:

+ *
    + *
  1. Language neutral
  2. + *
  3. Thread LANGID, based on the thread's locale value
  4. + *
  5. User default LANGID, based on the user's default locale value
  6. + *
  7. System default LANGID, based on the system default locale value
  8. + *
  9. US English
  10. + *
+ * * @param code The error code - * @return Formatted message. + * @param primaryLangId The primary language identifier + * @param sublangId The sublanguage identifier + * @return Formatted message in the specified locale. */ - public static String formatMessage(int code) { + public static String formatMessage(int code, int primaryLangId, int sublangId) { PointerByReference buffer = new PointerByReference(); int nLen = Kernel32.INSTANCE.FormatMessage( WinBase.FORMAT_MESSAGE_ALLOCATE_BUFFER @@ -193,7 +214,7 @@ public static String formatMessage(int code) { | WinBase.FORMAT_MESSAGE_IGNORE_INSERTS, null, code, - 0, // TODO: // MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT) + WinNT.LocaleMacros.MAKELANGID(primaryLangId, sublangId), buffer, 0, null); if (nLen == 0) { throw new LastErrorException(Native.getLastError()); diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32UtilTest.java b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32UtilTest.java index cd96bfbee1..cdb5c373f4 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32UtilTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32UtilTest.java @@ -159,6 +159,18 @@ public void testFormatMessageFromHR() { } } + public void testFormatMessageFromErrorCodeWithNonEnglishLocale() { + int errorCode = W32Errors.S_OK.intValue(); + String formattedMsgInDefaultLocale = Kernel32Util.formatMessage(errorCode); + // primary and sub languages id's of the english locale, because it is present on most machines + String formattedMsgInEnglishLocale = Kernel32Util.formatMessage(errorCode, 9, 1); + if(AbstractWin32TestSupport.isEnglishLocale) { + assertEquals(formattedMsgInDefaultLocale, formattedMsgInEnglishLocale); + } else { + assertNotSame(formattedMsgInDefaultLocale, formattedMsgInEnglishLocale); + } + } + public void testGetTempPath() { assertTrue(Kernel32Util.getTempPath().length() > 0); }