Skip to content

Commit

Permalink
Clean up manifest patch tool
Browse files Browse the repository at this point in the history
  • Loading branch information
fmeum committed Nov 3, 2024
1 parent 3383d4f commit 7976d91
Showing 1 changed file with 36 additions and 35 deletions.
71 changes: 36 additions & 35 deletions src/patch_java_manifest_for_utf8.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,71 +20,72 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

// This program patches the app manifest of the java.exe launcher to force its
// active code page to UTF-8. This is necessary because the launcher sets
// sun.jnu.encoding to the system code page, which by default is a legacy
// code page such as Cp1252 on Windows.
int wmain(int argc, wchar_t *argv[]) {
if (argc != 2) {
wprintf(L"Usage: %s <filename>\n", argv[0]);
fwprintf(stderr, L"Usage: %ls <filename>\n", argv[0]);
return 1;
}

// Read the app manifest (aka side-by-side or fusion manifest) from the
// executable, which requires loading it as a "module".
HMODULE exe = LoadLibraryExW(argv[1], nullptr, LOAD_LIBRARY_AS_DATAFILE);
if (!exe) {
wprintf(L"Error loading file: %s\n", argv[1]);
fwprintf(stderr, L"Error loading file %ls\n", argv[1]);
return 1;
}

HRSRC manifestResource = FindResourceA(exe, MAKEINTRESOURCE(1), RT_MANIFEST);
if (!manifestResource) {
HRSRC manifest_resource = FindResourceA(exe, MAKEINTRESOURCE(1), RT_MANIFEST);
if (!manifest_resource) {
fwprintf(stderr, L"Resource not found.\n");
return 1;
}

HGLOBAL manifestHandle = LoadResource(exe, manifestResource);
if (!manifestHandle) {
HGLOBAL manifest_handle = LoadResource(exe, manifest_resource);
if (!manifest_handle) {
fwprintf(stderr, L"Error loading resource.\n");
return 1;
}
LPVOID manifestData = LockResource(manifestHandle);
if (!manifestData) {
LPVOID manifest_data = LockResource(manifest_handle);
if (!manifest_data) {
fwprintf(stderr, L"Error locking resource.\n");
return 1;
}
DWORD manifestLen = SizeofResource(exe, manifestResource);

std::string manifest((char *) manifestData, manifestLen);
fwprintf(stderr, L"Manifest data: %s\n", manifest.c_str());

UnlockResource(manifestHandle);
FreeResource(manifestHandle);
DWORD manifest_len = SizeofResource(exe, manifest_resource);
std::string manifest((char *) manifest_data, manifest_len);
UnlockResource(manifest_handle);
FreeResource(manifest_handle);
FreeLibrary(exe);

std::size_t insertPos = manifest.find("</asmv3:windowsSettings>");
if (insertPos == std::wstring::npos) {
fwprintf(stderr, L"End tag not found.\n");
// Insert the activeCodePage element into the manifest at the end of the
// windowsSettings element.
// https://github.com/openjdk/jdk/blob/29882bfe7b7e76446a96862cd0a5e81c7e054415/src/java.base/windows/native/launcher/java.manifest#L43
std::size_t insert_pos = manifest.find("</asmv3:windowsSettings>");
if (insert_pos == std::wstring::npos) {
fwprintf(stderr, L"End tag not found in manifest:\n%s", manifest.c_str());
return 1;
}
std::string newManifest = manifest.substr(0, insertPos) +
std::string new_manifest = manifest.substr(0, insert_pos) +
"<activeCodePage xmlns=\"http://schemas.microsoft.com/SMI/2019/WindowsSettings\">UTF-8</activeCodePage>" +
manifest.substr(insertPos);
manifest.substr(insert_pos);

fwprintf(stderr, L"Modified manifest data: %ls\n", newManifest.c_str());

HANDLE updateHandle = BeginUpdateResourceW(argv[1], false);
if (!updateHandle) {
// Write back the modified app manifest.
HANDLE update_handle = BeginUpdateResourceW(argv[1], false);
if (!update_handle) {
fwprintf(stderr, L"Error opening file for update.\n");
return 1;
}

// Update the resource in the file
if (!UpdateResourceW(updateHandle,
MAKEINTRESOURCEW(1),
MAKEINTRESOURCEW(24),
if (!UpdateResourceA(update_handle,
MAKEINTRESOURCE(1),
RT_MANIFEST,
MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
(char *) newManifest.c_str(),
newManifest.size())) {
const_cast<char *>(new_manifest.c_str()),
new_manifest.size())) {
fwprintf(stderr, L"Error updating resource.\n");
return 1;
}

if (!EndUpdateResourceW(updateHandle, false)) {
if (!EndUpdateResourceW(update_handle, false)) {
fwprintf(stderr, L"Error finalizing update.\n");
return 1;
}
Expand Down

0 comments on commit 7976d91

Please sign in to comment.