Skip to content

Commit

Permalink
Merge branch 'pr-1482'
Browse files Browse the repository at this point in the history
  • Loading branch information
matthiasblaesing committed Dec 3, 2022
2 parents 74d59b9 + 2a27c26 commit 49d80ee
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Features
* [#1459](https://github.com/java-native-access/jna/pull/1459): Add `VirtualLock` and `VirtualUnlock` in `c.s.j.p.win32.Kernel32` - [@matthiasblaesing](https://github.com/matthiasblaesing).
* [#1471](https://github.com/java-native-access/jna/pull/1471): Add `c.s.j.p.win32.Advapi32Util#isCurrentProcessElevated` and associated Types - [@dbwiddis](https://github.com/dbwiddis).
* [#1474](https://github.com/java-native-access/jna/pull/1474): Add `c.s.j.p.win32.WbemCli#IWbemClassObject.IWbemQualifierSet`, `IWbemServices.GetObject`, `IWbemContext.SetValue` and associated methods - [@rchateauneu](https://github.com/rchateauneu).
* [#1482](https://github.com/java-native-access/jna/pull/1482): Add multilingual support of `Kernel32Util.formatMessage` - [@overpathz](https://github.com/overpathz).

Bug Fixes
---------
Expand Down
72 changes: 66 additions & 6 deletions contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java
Original file line number Diff line number Diff line change
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 All @@ -213,32 +234,71 @@ public static String formatMessage(int code) {
*
* @param code
* HRESULT
* @return Formatted message.
* @return Formatted message in the default locale.
*/
public static String formatMessage(HRESULT code) {
return formatMessage(code.intValue());
}

/**
* Format a message from an HRESULT.
*
* @param code
* HRESULT
* @param primaryLangId
* The primary language identifier
* @param sublangId
* The primary language identifier
* @return Formatted message in the specified locale.
*/
public static String formatMessage(HRESULT code, int primaryLangId, int sublangId) {
return formatMessage(code.intValue(), primaryLangId, sublangId);
}

/**
* Format a system message from an error code.
*
* @param code
* Error code, typically a result of GetLastError.
* @return Formatted message.
* @return Formatted message in the default locale.
*/
public static String formatMessageFromLastErrorCode(int code) {
return formatMessage(W32Errors.HRESULT_FROM_WIN32(code));
}

/**
* Format a system message from an error code.
*
* @param code
* Error code, typically a result of GetLastError.
* @param primaryLangId
* The primary language identifier
* @param sublangId
* The primary language identifier
* @return Formatted message in the specified locale.
*/
public static String formatMessageFromLastErrorCode(int code, int primaryLangId, int sublangId) {
return formatMessage(W32Errors.HRESULT_FROM_WIN32(code), primaryLangId, sublangId);
}

/**
* @return Obtains the human-readable error message text from the last error
* that occurred by invocating {@code Kernel32.GetLastError()}.
* that occurred by invocating {@code Kernel32.GetLastError()} in the default locale.
*/
public static String getLastErrorMessage() {
return Kernel32Util.formatMessageFromLastErrorCode(Kernel32.INSTANCE
.GetLastError());
}

/**
* @return Obtains the human-readable error message text from the last error
* that occurred by invocating {@code Kernel32.GetLastError()} in the specified locale.
*/
public static String getLastErrorMessage(int primaryLangId, int sublangId) {
return Kernel32Util.formatMessageFromLastErrorCode(Kernel32.INSTANCE
.GetLastError(), primaryLangId, sublangId);
}

/**
* Return the path designated for temporary files.
*
Expand Down
Original file line number Diff line number Diff line change
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 49d80ee

Please sign in to comment.