Skip to content

Commit

Permalink
Provide multilingual support of Kernel32Util.formatMessage()
Browse files Browse the repository at this point in the history
  • Loading branch information
overpathz committed Dec 1, 2022
1 parent 529b716 commit f93987b
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 3 deletions.
27 changes: 24 additions & 3 deletions contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java
Expand Up @@ -178,22 +178,43 @@ 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()}.
*
* <p>If you pass in zero, FormatMessage looks for a message for LANGIDs in the following order:</p>
* <ol>
* <li>Language neutral</li>
* <li>Thread LANGID, based on the thread's locale value</li>
* <li>User default LANGID, based on the user's default locale value</li>
* <li>System default LANGID, based on the system default locale value</li>
* <li>US English</li>
* </ol>
*
* @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
| WinBase.FORMAT_MESSAGE_FROM_SYSTEM
| 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());
Expand Down
Expand Up @@ -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);
}
Expand Down

0 comments on commit f93987b

Please sign in to comment.