From 6fb40871869ea5f9d6e85399dfde6f125ec2586a Mon Sep 17 00:00:00 2001 From: LoRd_MuldeR Date: Wed, 30 Sep 2020 14:15:06 +0200 Subject: [PATCH] Some improvements to Java executable verification. --- Makefile | 98 +++++++++++-------- .../res/templates/footer.mak | 4 +- .../res/templates/header.mak | 29 +++++- src/head.c | 86 +++++++++++++--- 4 files changed, 157 insertions(+), 60 deletions(-) diff --git a/Makefile b/Makefile index 815c304..dc884c7 100644 --- a/Makefile +++ b/Makefile @@ -11,67 +11,85 @@ # https://sourceforge.net/p/launch4j/ # ############################################################ -ifeq ($(words $(filter x86_64-%,$(shell $(CXX) -dumpmachine))),0) - CPU_ARCH := i586 +MACHINE := $(patsubst %-w64-mingw32,[%],$(shell $(CXX) -dumpmachine)) + +ifeq ($(MACHINE),[i686]) + CPU_ARCH := x86 + MARCH ?= i586 +else ifeq ($(MACHINE),[x86_64]) + CPU_ARCH := x64 + MARCH ?= x86-64 else - CPU_ARCH := x86-64 + $(error Unknown target machine "$(MACHINE)" encountered!) endif -MARCH ?= $(CPU_ARCH) +DEBUG ?= 0 MTUNE ?= generic -CFLAGS = -Os -static -municode -mwindows -march=$(MARCH) -mtune=$(MTUNE) +ifeq ($(DEBUG),0) + CFLAGS = -Os -static -static-libgcc -D_FORTIFY_SOURCE=2 -DNDEBUG + SUFFIX = exe +else + CFLAGS = -Og -g + SUFFIX = g.exe +endif + +CFLAGS += -municode -mwindows -march=$(MARCH) -mtune=$(MTUNE) .PHONY: all init resources build strip clean +ifeq ($(DEBUG),0) all: strip +else +all: build +endif init: mkdir -p bin mkdir -p obj resources: init + echo $(OS) windres -o obj/common.$(CPU_ARCH).o res/common.rc windres -o obj/splash_screen.$(CPU_ARCH).o res/splash_screen.rc windres -o obj/registry.$(CPU_ARCH).o res/registry.rc build: init resources - $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=0 -DL5J_DETECT_REGISTRY=0 -DL5J_STAY_ALIVE=1 -DL5J_ENABLE_SPLASH=1 -o bin/launch5j_$(CPU_ARCH).exe src/head.c obj/common.$(CPU_ARCH).o obj/splash_screen.$(CPU_ARCH).o - $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=0 -DL5J_DETECT_REGISTRY=0 -DL5J_STAY_ALIVE=1 -DL5J_ENABLE_SPLASH=0 -o bin/launch5j_$(CPU_ARCH)_nosplash.exe src/head.c obj/common.$(CPU_ARCH).o - $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=0 -DL5J_DETECT_REGISTRY=0 -DL5J_STAY_ALIVE=0 -DL5J_ENABLE_SPLASH=1 -o bin/launch5j_$(CPU_ARCH)_nowait.exe src/head.c obj/common.$(CPU_ARCH).o obj/splash_screen.$(CPU_ARCH).o - $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=0 -DL5J_DETECT_REGISTRY=0 -DL5J_STAY_ALIVE=0 -DL5J_ENABLE_SPLASH=0 -o bin/launch5j_$(CPU_ARCH)_nowait_nosplash.exe src/head.c obj/common.$(CPU_ARCH).o - $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=0 -DL5J_DETECT_REGISTRY=1 -DL5J_STAY_ALIVE=1 -DL5J_ENABLE_SPLASH=1 -o bin/launch5j_$(CPU_ARCH)_registry.exe src/head.c obj/common.$(CPU_ARCH).o obj/splash_screen.$(CPU_ARCH).o obj/registry.$(CPU_ARCH).o - $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=0 -DL5J_DETECT_REGISTRY=1 -DL5J_STAY_ALIVE=1 -DL5J_ENABLE_SPLASH=0 -o bin/launch5j_$(CPU_ARCH)_registry_nosplash.exe src/head.c obj/common.$(CPU_ARCH).o obj/registry.$(CPU_ARCH).o - $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=0 -DL5J_DETECT_REGISTRY=1 -DL5J_STAY_ALIVE=0 -DL5J_ENABLE_SPLASH=1 -o bin/launch5j_$(CPU_ARCH)_registry_nowait.exe src/head.c obj/common.$(CPU_ARCH).o obj/splash_screen.$(CPU_ARCH).o obj/registry.$(CPU_ARCH).o - $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=0 -DL5J_DETECT_REGISTRY=1 -DL5J_STAY_ALIVE=0 -DL5J_ENABLE_SPLASH=0 -o bin/launch5j_$(CPU_ARCH)_registry_nowait_nosplash.exe src/head.c obj/common.$(CPU_ARCH).o obj/registry.$(CPU_ARCH).o - $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=1 -DL5J_DETECT_REGISTRY=0 -DL5J_STAY_ALIVE=1 -DL5J_ENABLE_SPLASH=1 -o bin/launch5j_$(CPU_ARCH)_wrapped.exe src/head.c obj/common.$(CPU_ARCH).o obj/splash_screen.$(CPU_ARCH).o - $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=1 -DL5J_DETECT_REGISTRY=0 -DL5J_STAY_ALIVE=1 -DL5J_ENABLE_SPLASH=0 -o bin/launch5j_$(CPU_ARCH)_wrapped_nosplash.exe src/head.c obj/common.$(CPU_ARCH).o - $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=1 -DL5J_DETECT_REGISTRY=0 -DL5J_STAY_ALIVE=0 -DL5J_ENABLE_SPLASH=1 -o bin/launch5j_$(CPU_ARCH)_wrapped_nowait.exe src/head.c obj/common.$(CPU_ARCH).o obj/splash_screen.$(CPU_ARCH).o - $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=1 -DL5J_DETECT_REGISTRY=0 -DL5J_STAY_ALIVE=0 -DL5J_ENABLE_SPLASH=0 -o bin/launch5j_$(CPU_ARCH)_wrapped_nowait_nosplash.exe src/head.c obj/common.$(CPU_ARCH).o - $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=1 -DL5J_DETECT_REGISTRY=1 -DL5J_STAY_ALIVE=1 -DL5J_ENABLE_SPLASH=1 -o bin/launch5j_$(CPU_ARCH)_wrapped_registry.exe src/head.c obj/common.$(CPU_ARCH).o obj/splash_screen.$(CPU_ARCH).o obj/registry.$(CPU_ARCH).o - $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=1 -DL5J_DETECT_REGISTRY=1 -DL5J_STAY_ALIVE=1 -DL5J_ENABLE_SPLASH=0 -o bin/launch5j_$(CPU_ARCH)_wrapped_registry_nosplash.exe src/head.c obj/common.$(CPU_ARCH).o obj/registry.$(CPU_ARCH).o - $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=1 -DL5J_DETECT_REGISTRY=1 -DL5J_STAY_ALIVE=0 -DL5J_ENABLE_SPLASH=1 -o bin/launch5j_$(CPU_ARCH)_wrapped_registry_nowait.exe src/head.c obj/common.$(CPU_ARCH).o obj/splash_screen.$(CPU_ARCH).o obj/registry.$(CPU_ARCH).o - $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=1 -DL5J_DETECT_REGISTRY=1 -DL5J_STAY_ALIVE=0 -DL5J_ENABLE_SPLASH=0 -o bin/launch5j_$(CPU_ARCH)_wrapped_registry_nowait_nosplash.exe src/head.c obj/common.$(CPU_ARCH).o obj/registry.$(CPU_ARCH).o + $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=0 -DL5J_DETECT_REGISTRY=0 -DL5J_STAY_ALIVE=1 -DL5J_ENABLE_SPLASH=1 -o bin/launch5j_$(CPU_ARCH).$(SUFFIX) src/head.c obj/common.$(CPU_ARCH).o obj/splash_screen.$(CPU_ARCH).o + $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=0 -DL5J_DETECT_REGISTRY=0 -DL5J_STAY_ALIVE=1 -DL5J_ENABLE_SPLASH=0 -o bin/launch5j_$(CPU_ARCH)_nosplash.$(SUFFIX) src/head.c obj/common.$(CPU_ARCH).o + $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=0 -DL5J_DETECT_REGISTRY=0 -DL5J_STAY_ALIVE=0 -DL5J_ENABLE_SPLASH=1 -o bin/launch5j_$(CPU_ARCH)_nowait.$(SUFFIX) src/head.c obj/common.$(CPU_ARCH).o obj/splash_screen.$(CPU_ARCH).o + $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=0 -DL5J_DETECT_REGISTRY=0 -DL5J_STAY_ALIVE=0 -DL5J_ENABLE_SPLASH=0 -o bin/launch5j_$(CPU_ARCH)_nowait_nosplash.$(SUFFIX) src/head.c obj/common.$(CPU_ARCH).o + $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=0 -DL5J_DETECT_REGISTRY=1 -DL5J_STAY_ALIVE=1 -DL5J_ENABLE_SPLASH=1 -o bin/launch5j_$(CPU_ARCH)_registry.$(SUFFIX) src/head.c obj/common.$(CPU_ARCH).o obj/splash_screen.$(CPU_ARCH).o obj/registry.$(CPU_ARCH).o + $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=0 -DL5J_DETECT_REGISTRY=1 -DL5J_STAY_ALIVE=1 -DL5J_ENABLE_SPLASH=0 -o bin/launch5j_$(CPU_ARCH)_registry_nosplash.$(SUFFIX) src/head.c obj/common.$(CPU_ARCH).o obj/registry.$(CPU_ARCH).o + $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=0 -DL5J_DETECT_REGISTRY=1 -DL5J_STAY_ALIVE=0 -DL5J_ENABLE_SPLASH=1 -o bin/launch5j_$(CPU_ARCH)_registry_nowait.$(SUFFIX) src/head.c obj/common.$(CPU_ARCH).o obj/splash_screen.$(CPU_ARCH).o obj/registry.$(CPU_ARCH).o + $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=0 -DL5J_DETECT_REGISTRY=1 -DL5J_STAY_ALIVE=0 -DL5J_ENABLE_SPLASH=0 -o bin/launch5j_$(CPU_ARCH)_registry_nowait_nosplash.$(SUFFIX) src/head.c obj/common.$(CPU_ARCH).o obj/registry.$(CPU_ARCH).o + $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=1 -DL5J_DETECT_REGISTRY=0 -DL5J_STAY_ALIVE=1 -DL5J_ENABLE_SPLASH=1 -o bin/launch5j_$(CPU_ARCH)_wrapped.$(SUFFIX) src/head.c obj/common.$(CPU_ARCH).o obj/splash_screen.$(CPU_ARCH).o + $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=1 -DL5J_DETECT_REGISTRY=0 -DL5J_STAY_ALIVE=1 -DL5J_ENABLE_SPLASH=0 -o bin/launch5j_$(CPU_ARCH)_wrapped_nosplash.$(SUFFIX) src/head.c obj/common.$(CPU_ARCH).o + $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=1 -DL5J_DETECT_REGISTRY=0 -DL5J_STAY_ALIVE=0 -DL5J_ENABLE_SPLASH=1 -o bin/launch5j_$(CPU_ARCH)_wrapped_nowait.$(SUFFIX) src/head.c obj/common.$(CPU_ARCH).o obj/splash_screen.$(CPU_ARCH).o + $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=1 -DL5J_DETECT_REGISTRY=0 -DL5J_STAY_ALIVE=0 -DL5J_ENABLE_SPLASH=0 -o bin/launch5j_$(CPU_ARCH)_wrapped_nowait_nosplash.$(SUFFIX) src/head.c obj/common.$(CPU_ARCH).o + $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=1 -DL5J_DETECT_REGISTRY=1 -DL5J_STAY_ALIVE=1 -DL5J_ENABLE_SPLASH=1 -o bin/launch5j_$(CPU_ARCH)_wrapped_registry.$(SUFFIX) src/head.c obj/common.$(CPU_ARCH).o obj/splash_screen.$(CPU_ARCH).o obj/registry.$(CPU_ARCH).o + $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=1 -DL5J_DETECT_REGISTRY=1 -DL5J_STAY_ALIVE=1 -DL5J_ENABLE_SPLASH=0 -o bin/launch5j_$(CPU_ARCH)_wrapped_registry_nosplash.$(SUFFIX) src/head.c obj/common.$(CPU_ARCH).o obj/registry.$(CPU_ARCH).o + $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=1 -DL5J_DETECT_REGISTRY=1 -DL5J_STAY_ALIVE=0 -DL5J_ENABLE_SPLASH=1 -o bin/launch5j_$(CPU_ARCH)_wrapped_registry_nowait.$(SUFFIX) src/head.c obj/common.$(CPU_ARCH).o obj/splash_screen.$(CPU_ARCH).o obj/registry.$(CPU_ARCH).o + $(CC) $(CFLAGS) -DL5J_JAR_FILE_WRAPPED=1 -DL5J_DETECT_REGISTRY=1 -DL5J_STAY_ALIVE=0 -DL5J_ENABLE_SPLASH=0 -o bin/launch5j_$(CPU_ARCH)_wrapped_registry_nowait_nosplash.$(SUFFIX) src/head.c obj/common.$(CPU_ARCH).o obj/registry.$(CPU_ARCH).o strip: build - strip bin/launch5j_$(CPU_ARCH).exe - strip bin/launch5j_$(CPU_ARCH)_nosplash.exe - strip bin/launch5j_$(CPU_ARCH)_nowait.exe - strip bin/launch5j_$(CPU_ARCH)_nowait_nosplash.exe - strip bin/launch5j_$(CPU_ARCH)_registry.exe - strip bin/launch5j_$(CPU_ARCH)_registry_nosplash.exe - strip bin/launch5j_$(CPU_ARCH)_registry_nowait.exe - strip bin/launch5j_$(CPU_ARCH)_registry_nowait_nosplash.exe - strip bin/launch5j_$(CPU_ARCH)_wrapped.exe - strip bin/launch5j_$(CPU_ARCH)_wrapped_nosplash.exe - strip bin/launch5j_$(CPU_ARCH)_wrapped_nowait.exe - strip bin/launch5j_$(CPU_ARCH)_wrapped_nowait_nosplash.exe - strip bin/launch5j_$(CPU_ARCH)_wrapped_registry.exe - strip bin/launch5j_$(CPU_ARCH)_wrapped_registry_nosplash.exe - strip bin/launch5j_$(CPU_ARCH)_wrapped_registry_nowait.exe - strip bin/launch5j_$(CPU_ARCH)_wrapped_registry_nowait_nosplash.exe + strip bin/launch5j_$(CPU_ARCH).$(SUFFIX) + strip bin/launch5j_$(CPU_ARCH)_nosplash.$(SUFFIX) + strip bin/launch5j_$(CPU_ARCH)_nowait.$(SUFFIX) + strip bin/launch5j_$(CPU_ARCH)_nowait_nosplash.$(SUFFIX) + strip bin/launch5j_$(CPU_ARCH)_registry.$(SUFFIX) + strip bin/launch5j_$(CPU_ARCH)_registry_nosplash.$(SUFFIX) + strip bin/launch5j_$(CPU_ARCH)_registry_nowait.$(SUFFIX) + strip bin/launch5j_$(CPU_ARCH)_registry_nowait_nosplash.$(SUFFIX) + strip bin/launch5j_$(CPU_ARCH)_wrapped.$(SUFFIX) + strip bin/launch5j_$(CPU_ARCH)_wrapped_nosplash.$(SUFFIX) + strip bin/launch5j_$(CPU_ARCH)_wrapped_nowait.$(SUFFIX) + strip bin/launch5j_$(CPU_ARCH)_wrapped_nowait_nosplash.$(SUFFIX) + strip bin/launch5j_$(CPU_ARCH)_wrapped_registry.$(SUFFIX) + strip bin/launch5j_$(CPU_ARCH)_wrapped_registry_nosplash.$(SUFFIX) + strip bin/launch5j_$(CPU_ARCH)_wrapped_registry_nowait.$(SUFFIX) + strip bin/launch5j_$(CPU_ARCH)_wrapped_registry_nowait_nosplash.$(SUFFIX) clean: init - rm -f bin/*.exe - rm -f obj/*.o - + $(RM) bin/*.$(SUFFIX) + $(RM) obj/*.o diff --git a/etc/utils/MakefileGenerator/res/templates/footer.mak b/etc/utils/MakefileGenerator/res/templates/footer.mak index ff790e6..46d3f0e 100644 --- a/etc/utils/MakefileGenerator/res/templates/footer.mak +++ b/etc/utils/MakefileGenerator/res/templates/footer.mak @@ -1,3 +1,3 @@ clean: init - rm -f bin/*.exe - rm -f obj/*.o + $(RM) bin/*.$(SUFFIX) + $(RM) obj/*.o diff --git a/etc/utils/MakefileGenerator/res/templates/header.mak b/etc/utils/MakefileGenerator/res/templates/header.mak index 9da7d90..ed94d84 100644 --- a/etc/utils/MakefileGenerator/res/templates/header.mak +++ b/etc/utils/MakefileGenerator/res/templates/header.mak @@ -11,26 +11,45 @@ # https://sourceforge.net/p/launch4j/ # ############################################################ -ifeq ($(words $(filter x86_64-%,$(shell $(CXX) -dumpmachine))),0) - CPU_ARCH := i586 +MACHINE := $(patsubst %-w64-mingw32,[%],$(shell $(CXX) -dumpmachine)) + +ifeq ($(MACHINE),[i686]) + CPU_ARCH := x86 + MARCH ?= i586 +else ifeq ($(MACHINE),[x86_64]) + CPU_ARCH := x64 + MARCH ?= x86-64 else - CPU_ARCH := x86-64 + $(error Unknown target machine "$(MACHINE)" encountered!) endif -MARCH ?= $(CPU_ARCH) +DEBUG ?= 0 MTUNE ?= generic -CFLAGS = -Os -static -municode -mwindows -march=$(MARCH) -mtune=$(MTUNE) +ifeq ($(DEBUG),0) + CFLAGS = -Os -static -static-libgcc -D_FORTIFY_SOURCE=2 -DNDEBUG + SUFFIX = exe +else + CFLAGS = -Og -g + SUFFIX = g.exe +endif + +CFLAGS += -municode -mwindows -march=$(MARCH) -mtune=$(MTUNE) .PHONY: all init resources build strip clean +ifeq ($(DEBUG),0) all: strip +else +all: build +endif init: mkdir -p bin mkdir -p obj resources: init + echo $(OS) windres -o obj/common.$(CPU_ARCH).o res/common.rc windres -o obj/splash_screen.$(CPU_ARCH).o res/splash_screen.rc windres -o obj/registry.$(CPU_ARCH).o res/registry.rc diff --git a/src/head.c b/src/head.c index 00e8ff7..8bb9d54 100644 --- a/src/head.c +++ b/src/head.c @@ -253,6 +253,41 @@ static const wchar_t *skip_leading_separator(const wchar_t *path) return path; } +static const wchar_t *get_absolute_path(const wchar_t *const path) +{ + DWORD buff_len = 0U; + wchar_t *buffer = NULL; + + if (NOT_EMPTY(path)) + { + for (;;) + { + const DWORD result = GetFullPathNameW(path, buff_len, buffer, NULL); + if (result > 0U) + { + if (result < buff_len) + { + return buffer; + } + else + { + if (!(buffer = (wchar_t*) realloc(buffer, sizeof(wchar_t) * (buff_len = result)))) + { + break; + } + } + } + else + { + break; /*error*/ + } + } + } + + free(buffer); + return NULL; +} + static BOOL file_exists(const wchar_t *const filename) { struct _stat buffer; if (_wstat(filename, &buffer) == 0) @@ -262,6 +297,22 @@ static BOOL file_exists(const wchar_t *const filename) { return FALSE; } +static UINT file_is_executable(const wchar_t *const file_path) +{ + DWORD binary_type = 0U; + if(GetBinaryTypeW(file_path, &binary_type)) + { + switch(binary_type) + { + case SCS_32BIT_BINARY: + return 32U; + case SCS_64BIT_BINARY: + return 64U; + } + } + return 0U; +} + /* ======================================================================== */ /* Resource routines */ /* ======================================================================== */ @@ -608,17 +659,23 @@ static const wchar_t *detect_java_runtime_verify(const BOOL flag_x64, const HKEY if (NOT_EMPTY(java_home_path)) { + const UINT required_bitness = flag_x64 ? 64U : 32U; for (size_t i = 0U; REL_PATHS[i]; ++i) { - wchar_t *const java_executable_path = awprintf(REL_PATHS[i], java_home_path); + const wchar_t *const java_executable_path = awprintf(REL_PATHS[i], java_home_path); if (java_executable_path) { - if (file_exists(java_executable_path)) + const wchar_t *const full_executable_abspath = get_absolute_path(java_executable_path); + if (full_executable_abspath) { - result = java_executable_path; - break; + if (file_is_executable(full_executable_abspath) == required_bitness) + { + result = full_executable_abspath; + break; + } + free((void*)full_executable_abspath); } - free(java_executable_path); + free((void*)java_executable_path); } } } @@ -1113,15 +1170,18 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine } #else jre_relative_path = load_string(hInstance, ID_STR_JREPATH); - if (!(java_runtime_path = awprintf(L"%ls\\%ls", executable_directory, AVAILABLE(jre_relative_path) ? skip_leading_separator(jre_relative_path) : JRE_RELATIVE_PATH_DEFAULT))) { - show_message(hwnd, MB_ICONERROR | MB_TOPMOST, APP_HEADING, L"The path of the Java runtime could not be determined!"); - goto cleanup; - } - if (!file_exists(java_runtime_path)) - { - show_message_format(hwnd, MB_ICONERROR | MB_TOPMOST, APP_HEADING, L"The required Java runtime could not be found:\n\n%ls\n\n\nRe-installing the application may fix the problem!", java_runtime_path); - goto cleanup; + const wchar_t *const relative_path_ptr = AVAILABLE(jre_relative_path) ? skip_leading_separator(jre_relative_path) : NULL; + if (!(java_runtime_path = awprintf(L"%ls\\%ls", executable_directory, NOT_EMPTY(relative_path_ptr) ? relative_path_ptr: JRE_RELATIVE_PATH_DEFAULT))) + { + show_message(hwnd, MB_ICONERROR | MB_TOPMOST, APP_HEADING, L"The path of the Java runtime could not be determined!"); + goto cleanup; + } + if (!file_is_executable(java_runtime_path)) + { + show_message_format(hwnd, MB_ICONERROR | MB_TOPMOST, APP_HEADING, L"The Java runtime could not be found or is invalid:\n\n%ls\n\n\nRe-installing the application may fix the problem!", java_runtime_path); + goto cleanup; + } } #endif