提交 e0933fb3 编写于 作者: H herrick

6797688: Umbrella: Merge all JDK 6u4 - 6u12 deployment code into JDK7

6845973: Update JDK7 with deployment changes in 6u13, 6u14
4802695: Support 64-bit Java Plug-in and Java webstart on Windows/Linux on AMD64
6825019: DownloadManager should not be loaded and referenced for full JRE
6738770: REGRESSION:JSException throws when use LiveConnect javascript facility
6772884: plugin2 : java.lang.OutOfMemoryError or crash
6707535: Crossing domain hole affecting multiple sites/domains using plug-in
6728071: Non-verification of Update files may allow unintended updates
6704154: Code loaded from local filesystem should not get access to localhost
6727081: Web Start security restrictions bypass using special extension jnlp
6727079: Java Web Start Socket() restriction bypass
6727071: Cache location/user name information disclosure in SingleInstanceImpl.
6716217: AppletClassLoader adds permissions based on codebase regardless of CS
6694892: Java Webstart inclusion via system properties override [CVE-2008-2086]
6704074: localhost socket access due to cache location exposed
6703909: Java webstart arbitrary file creation using nativelib
6665315: browser crashes when deployment.properties has more slashes ( / )
6660121: Encoding values in JNLP files can cause buffer overflow
6606110: URLConnection.setProxiedHost for resources that are loaded via proxy
6581221: SSV(VISTA): Redirection FAILS to work if user does a downgrade install
6609756: Buffer Overflow in Java ActiveX component
6608712: Bypassing the same origin policy in Java with crafted names
6534630: "gnumake clobber" doesn't
6849953: JDK7 - replacement of bufferoverflowU.lib on amd64 breaks build
6849029: Need some JDK7 merge clean-up after comments on the webrev
6847582: Build problem on JDK7 with isSecureProperty in merge
6827935: JDK 7 deployment merging - problem in Compiler-msvm.gmk
6823215: latest merge fixes from 6u12 -> JDK7
6816153: further mergers for JDK7 deployment integration
6807074: Fix Java Kernel and JQS in initial JDK7 builds
Summary: Initial changeset for implementing 6uX Deployment Features into JDK7
Reviewed-by: dgu, billyh
上级 a7445907
...@@ -91,10 +91,10 @@ ifeq ($(PLATFORM), windows) ...@@ -91,10 +91,10 @@ ifeq ($(PLATFORM), windows)
CXXFLAGS_COMMON += $(MS_RUNTIME_OPTION) CXXFLAGS_COMMON += $(MS_RUNTIME_OPTION)
LDOUTPUT = -Fe LDOUTPUT = -Fe
# J2SE name required here # JDK name required here
RC_FLAGS += /D "J2SE_FNAME=$(PGRM).exe" \ RC_FLAGS += /D "JDK_FNAME=$(PGRM).exe" \
/D "J2SE_INTERNAL_NAME=$(PGRM)" \ /D "JDK_INTERNAL_NAME=$(PGRM)" \
/D "J2SE_FTYPE=0x1L" /D "JDK_FTYPE=0x1L"
RES = $(OBJDIR)/$(PGRM).res RES = $(OBJDIR)/$(PGRM).res
else else
...@@ -133,13 +133,19 @@ unpacker: ...@@ -133,13 +133,19 @@ unpacker:
$(MAKE) $(UNPACK_EXE) STANDALONE=true LDMAPFLAGS_OPT= LDMAPFLAGS_DBG= $(MAKE) $(UNPACK_EXE) STANDALONE=true LDMAPFLAGS_OPT= LDMAPFLAGS_DBG=
ifeq ($(PLATFORM), windows) ifeq ($(PLATFORM), windows)
IMVERSIONVALUE=$(JDK_MINOR_VERSION).$(JDK_MICRO_VERSION).$(JDK_UPDATE_VER).$(COOKED_BUILD_NUMBER)
SED_ALL_MANIFEST=$(SED) -e 's%IMVERSION%$(IMVERSIONVALUE)%g'
updatefiles::
$(CAT) $(TOPDIR)/src/windows/resource/unpack200_proto.exe.manifest | $(SED_ALL_MANIFEST) > $(OBJDIR)/unpack200.exe.manifest
winres:: $(RES) winres:: $(RES)
else else
updatefiles::
$(ECHO) "Manifest not required for Unix"
winres:: winres::
$(ECHO) "Resource files not required for Unix" $(ECHO) "Resource files not required for Unix"
endif endif
$(UNPACK_EXE): $(UNPACK_EXE_FILES_o) winres $(UNPACK_EXE): $(UNPACK_EXE_FILES_o) updatefiles winres
$(prep-target) $(prep-target)
$(LINKER) $(LDDFLAGS) $(UNPACK_EXE_FILES_o) $(RES) $(LIBCXX) $(LDOUTPUT)$(TEMPDIR)/unpack200$(EXE_SUFFIX) $(LINKER) $(LDDFLAGS) $(UNPACK_EXE_FILES_o) $(RES) $(LIBCXX) $(LDOUTPUT)$(TEMPDIR)/unpack200$(EXE_SUFFIX)
ifdef MT ifdef MT
......
# #
# Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. # Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
...@@ -464,11 +464,48 @@ JDK_RC_NAME = \ ...@@ -464,11 +464,48 @@ JDK_RC_NAME = \
JDK_RC_FVER = \ JDK_RC_FVER = \
$(JDK_MINOR_VERSION),$(JDK_MICRO_VERSION),$(JDK_UPDATE_VER),$(COOKED_BUILD_NUMBER) $(JDK_MINOR_VERSION),$(JDK_MICRO_VERSION),$(JDK_UPDATE_VER),$(COOKED_BUILD_NUMBER)
# J2SE name required here # JDK name required here
RC_FLAGS += -d "J2SE_BUILD_ID=$(JDK_RC_BUILD_ID)" \ RC_FLAGS += -d "JDK_BUILD_ID=$(JDK_RC_BUILD_ID)" \
-d "J2SE_COMPANY=$(JDK_RC_COMPANY)" \ -d "JDK_COMPANY=$(JDK_RC_COMPANY)" \
-d "J2SE_COMPONENT=$(JDK_RC_COMPONENT)" \ -d "JDK_COMPONENT=$(JDK_RC_COMPONENT)" \
-d "J2SE_VER=$(JDK_RC_VER)" \ -d "JDK_VER=$(JDK_RC_VER)" \
-d "J2SE_COPYRIGHT=$(JDK_RC_COPYRIGHT)" \ -d "JDK_COPYRIGHT=$(JDK_RC_COPYRIGHT)" \
-d "J2SE_NAME=$(JDK_RC_NAME)" \ -d "JDK_NAME=$(JDK_RC_NAME)" \
-d "J2SE_FVER=$(JDK_RC_FVER)" -d "JDK_FVER=$(JDK_RC_FVER)"
# Enable 7-Zip LZMA file (de)compression for Java Kernel if it is available
ifeq ($(ARCH_DATA_MODEL), 32)
ifneq ($(KERNEL), off)
# This is a hack to use until 7-Zip (and UPX) bundles can be put
# under /java/devtools.
ifndef DEPLOY_TOPDIR
DEPLOY_TOPDIR=$(JDK_TOPDIR)/../deploy
endif
# Uncomment this block to cause build failure if above assumption false
#DCHK = $(shell if [ ! -d $(DEPLOY_TOPDIR) ] ; then \
# $(ECHO) deploy_not_a_peer_of_j2se ; \
#fi )
#ifeq ($(DCHK), deploy_not_a_peer_of_j2se)
# If a build failure points to control coming here it means
# it means deploy is not in the same directory
# as j2se. Java Kernel can't tolerate that for the time being.
#endif
EC_TMP = $(shell if [ -d $(DEPLOY_TOPDIR)/make/lzma ] ; then \
$(ECHO) true ; \
else \
$(ECHO) false ; \
fi )
ifeq ($(EC_TMP), true)
EXTRA_COMP_INSTALL_PATH = lib\\\\deploy\\\\lzma.dll
# Crazy but true: deploy/make/plugin/jinstall/Makefile.jkernel does
# not include deploy/make/common/Defs-windows.gmk, either directly
# or indirectly. But it does include this file, so redundantly declare
# these variables that are in deploy/make/common/Defs-windows.gmk for
# the sake of the Java Kernel part of the deploy build. Whew!
EXTRA_COMP_LIB_NAME = lzma.dll
EXTRA_COMP_PATH = $(OUTPUTDIR)/tmp/deploy/lzma/win32/obj
EXTRA_COMP_CMD_PATH = $(EXTRA_COMP_PATH)/lzma.exe
EXTRA_COMP_LIB_PATH = $(EXTRA_COMP_PATH)/$(EXTRA_COMP_LIB_NAME)
endif
endif
endif
...@@ -207,10 +207,10 @@ ifndef LOCAL_RESOURCE_FILE ...@@ -207,10 +207,10 @@ ifndef LOCAL_RESOURCE_FILE
endif endif
@$(ECHO) Created $@ @$(ECHO) Created $@
# J2SE name required here # JDK name required here
RC_FLAGS += /D "J2SE_FNAME=$(LIBRARY).dll" \ RC_FLAGS += /D "JDK_FNAME=$(LIBRARY).dll" \
/D "J2SE_INTERNAL_NAME=$(LIBRARY)" \ /D "JDK_INTERNAL_NAME=$(LIBRARY)" \
/D "J2SE_FTYPE=0x2L" /D "JDK_FTYPE=0x2L"
$(OBJDIR)/$(LIBRARY).res: $(VERSIONINFO_RESOURCE) $(OBJDIR)/$(LIBRARY).res: $(VERSIONINFO_RESOURCE)
ifndef LOCAL_RESOURCE_FILE ifndef LOCAL_RESOURCE_FILE
......
...@@ -123,10 +123,10 @@ $(ACTUAL_PROGRAM):: classes $(JVMCFG) $(INIT) ...@@ -123,10 +123,10 @@ $(ACTUAL_PROGRAM):: classes $(JVMCFG) $(INIT)
# #
ifeq ($(PLATFORM), windows) ifeq ($(PLATFORM), windows)
# J2SE name required here # JDK name required here
RC_FLAGS += /D "J2SE_FNAME=$(PROGRAM)$(EXE_SUFFIX)" \ RC_FLAGS += /D "JDK_FNAME=$(PROGRAM)$(EXE_SUFFIX)" \
/D "J2SE_INTERNAL_NAME=$(PROGRAM)" \ /D "JDK_INTERNAL_NAME=$(PROGRAM)" \
/D "J2SE_FTYPE=0x1L" /D "JDK_FTYPE=0x1L"
$(OBJDIR)/$(PROGRAM).res: $(VERSIONINFO_RESOURCE) $(OBJDIR)/$(PROGRAM).res: $(VERSIONINFO_RESOURCE)
@$(prep-target) @$(prep-target)
......
...@@ -797,6 +797,11 @@ ifeq ($(PLATFORM), windows) ...@@ -797,6 +797,11 @@ ifeq ($(PLATFORM), windows)
$(CD) $(JRE_IMAGE_DIR)/lib && \ $(CD) $(JRE_IMAGE_DIR)/lib && \
$(RM) java.$(LIB_SUFFIX) jvm.$(LIB_SUFFIX) \ $(RM) java.$(LIB_SUFFIX) jvm.$(LIB_SUFFIX) \
hpi.$(LIB_SUFFIX) awt.$(LIB_SUFFIX) jawt.$(LIB_SUFFIX) hpi.$(LIB_SUFFIX) awt.$(LIB_SUFFIX) jawt.$(LIB_SUFFIX)
ifeq ($(ARCH_DATA_MODEL), 32)
@# The Java Kernel JRE image ships with a special VM. It is not included
@# in the full JRE image, so remove it. Also, is it only for 32-bit windows.
$(CD) $(JRE_IMAGE_DIR)/bin && $(RM) -r kernel
endif
endif # Windows endif # Windows
ifneq ($(PLATFORM), windows) ifneq ($(PLATFORM), windows)
$(call copy-man-pages,$(JRE_IMAGE_DIR),$(JRE_MAN_PAGES)) $(call copy-man-pages,$(JRE_IMAGE_DIR),$(JRE_MAN_PAGES))
......
...@@ -35,8 +35,8 @@ ifeq ($(PLATFORM), windows) ...@@ -35,8 +35,8 @@ ifeq ($(PLATFORM), windows)
LIBEXE = $(COMPILER_PATH)lib LIBEXE = $(COMPILER_PATH)lib
LINK = $(COMPILER_PATH)link LINK = $(COMPILER_PATH)link
RC = $(MSDEVTOOLS_PATH)rc RC = $(MSDEVTOOLS_PATH)rc
RSC = $(MSDEVTOOLS_PATH)rc
LINK32 = $(LINK) LINK32 = $(LINK)
RSC = $(RC)
# Fill in unknown values # Fill in unknown values
COMPILER_NAME=Unknown MSVC Compiler COMPILER_NAME=Unknown MSVC Compiler
...@@ -98,6 +98,9 @@ ifeq ($(PLATFORM), windows) ...@@ -98,6 +98,9 @@ ifeq ($(PLATFORM), windows)
endif endif
ifeq ($(CC_MAJORVER), 14) ifeq ($(CC_MAJORVER), 14)
ifeq ($(ARCH), amd64) ifeq ($(ARCH), amd64)
#rebase and midl moved out of Visual Studio into the SDK:
REBASE = $(MSDEVTOOLS_PATH)/rebase
MTL = $(MSDEVTOOLS_PATH)/midl.exe
ifeq ($(CC_MICROVER), 30701) ifeq ($(CC_MICROVER), 30701)
# This should be: CC_VER=14.00.30701 LINK_VER=8.00.30701 # This should be: CC_VER=14.00.30701 LINK_VER=8.00.30701
# WARNING: it says 14, but it is such an early build it doesn't # WARNING: it says 14, but it is such an early build it doesn't
...@@ -110,6 +113,8 @@ ifeq ($(PLATFORM), windows) ...@@ -110,6 +113,8 @@ ifeq ($(PLATFORM), windows)
COMPILER_NAME=Microsoft Platform SDK - April 2005 Edition (3790.1830) COMPILER_NAME=Microsoft Platform SDK - April 2005 Edition (3790.1830)
COMPILER_VERSION=VS2005 COMPILER_VERSION=VS2005
endif endif
else
REBASE = $(COMPILER_PATH)../rebase
endif endif
endif endif
ifeq ($(CC_MAJORVER), 15) ifeq ($(CC_MAJORVER), 15)
...@@ -120,7 +125,6 @@ ifeq ($(PLATFORM), windows) ...@@ -120,7 +125,6 @@ ifeq ($(PLATFORM), windows)
endif endif
# This will cause problems if ALT_COMPILER_PATH is defined to "" # This will cause problems if ALT_COMPILER_PATH is defined to ""
# which is a directive to use the PATH. # which is a directive to use the PATH.
REBASE = $(COMPILER_PATH)../REBASE
ifndef COMPILER_PATH ifndef COMPILER_PATH
COMPILER_PATH := $(error COMPILER_PATH cannot be empty here) COMPILER_PATH := $(error COMPILER_PATH cannot be empty here)
endif endif
......
...@@ -72,6 +72,7 @@ ADB = $(UTILS_COMMAND_PATH)adb ...@@ -72,6 +72,7 @@ ADB = $(UTILS_COMMAND_PATH)adb
AR = $(UTILS_CCS_BIN_PATH)ar AR = $(UTILS_CCS_BIN_PATH)ar
AS = $(UTILS_CCS_BIN_PATH)as AS = $(UTILS_CCS_BIN_PATH)as
BASENAME = $(UTILS_COMMAND_PATH)basename BASENAME = $(UTILS_COMMAND_PATH)basename
BZIP2 = $(UTILS_COMMAND_PATH)bzip2
CAT = $(UTILS_COMMAND_PATH)cat CAT = $(UTILS_COMMAND_PATH)cat
CHMOD = $(UTILS_COMMAND_PATH)chmod CHMOD = $(UTILS_COMMAND_PATH)chmod
CMP = $(UTILS_USR_BIN_PATH)cmp CMP = $(UTILS_USR_BIN_PATH)cmp
...@@ -157,6 +158,7 @@ ifeq ($(PLATFORM),windows) ...@@ -157,6 +158,7 @@ ifeq ($(PLATFORM),windows)
endif endif
# Re-define some utilities # Re-define some utilities
LEX =# override GNU Make intrinsic: no lex on windows LEX =# override GNU Make intrinsic: no lex on windows
SHA1SUM = $(UNIXCOMMAND_PATH)openssl sha1
endif endif
# Linux specific # Linux specific
......
...@@ -518,7 +518,7 @@ ifdef ALT_INSTALL_MSSDK ...@@ -518,7 +518,7 @@ ifdef ALT_INSTALL_MSSDK
xALT_INSTALL_MSSDK :="$(subst \,/,$(ALT_INSTALL_MSSDK))" xALT_INSTALL_MSSDK :="$(subst \,/,$(ALT_INSTALL_MSSDK))"
INSTALL_MSSDK :=$(call FullPath,$(xALT_INSTALL_MSSDK)) INSTALL_MSSDK :=$(call FullPath,$(xALT_INSTALL_MSSDK))
else else
INSTALL_MSSDK :=$(_psdk) INSTALL_MSSDK :=$(_ms_sdk)
endif endif
INSTALL_MSSDK:=$(call AltCheckSpaces,INSTALL_MSSDK) INSTALL_MSSDK:=$(call AltCheckSpaces,INSTALL_MSSDK)
...@@ -645,6 +645,17 @@ ifeq ($(ARCH_DATA_MODEL), 32) ...@@ -645,6 +645,17 @@ ifeq ($(ARCH_DATA_MODEL), 32)
HOTSPOT_CLIENT_PATH:=$(call AltCheckValue,HOTSPOT_CLIENT_PATH) HOTSPOT_CLIENT_PATH:=$(call AltCheckValue,HOTSPOT_CLIENT_PATH)
endif endif
# HOTSPOT_KERNEL_PATH: location of kernel jvm library file.
ifeq ($(ARCH_DATA_MODEL), 32)
ifdef ALT_HOTSPOT_KERNEL_PATH
HOTSPOT_KERNEL_PATH :=$(call FullPath,$(ALT_HOTSPOT_KERNEL_PATH))
else
HOTSPOT_KERNEL_PATH =$(HOTSPOT_IMPORT_PATH)/$(ARCH_VM_SUBDIR)/kernel
endif
HOTSPOT_KERNEL_PATH:=$(call AltCheckSpaces,HOTSPOT_KERNEL_PATH)
HOTSPOT_KERNEL_PATH:=$(call AltCheckValue,HOTSPOT_KERNEL_PATH)
endif
# HOTSPOT_SERVER_PATH: location of server jvm library file. # HOTSPOT_SERVER_PATH: location of server jvm library file.
ifdef ALT_HOTSPOT_SERVER_PATH ifdef ALT_HOTSPOT_SERVER_PATH
HOTSPOT_SERVER_PATH :=$(call FullPath,$(ALT_HOTSPOT_SERVER_PATH)) HOTSPOT_SERVER_PATH :=$(call FullPath,$(ALT_HOTSPOT_SERVER_PATH))
...@@ -663,4 +674,3 @@ else ...@@ -663,4 +674,3 @@ else
endif endif
HOTSPOT_LIB_PATH:=$(call AltCheckSpaces,HOTSPOT_LIB_PATH) HOTSPOT_LIB_PATH:=$(call AltCheckSpaces,HOTSPOT_LIB_PATH)
HOTSPOT_LIB_PATH:=$(call AltCheckValue,HOTSPOT_LIB_PATH) HOTSPOT_LIB_PATH:=$(call AltCheckValue,HOTSPOT_LIB_PATH)
...@@ -277,6 +277,7 @@ endif ...@@ -277,6 +277,7 @@ endif
PROMOTED_RE_AREA = $(SLASH_JAVA)/re/jdk/$(JDK_VERSION)/promoted PROMOTED_RE_AREA = $(SLASH_JAVA)/re/jdk/$(JDK_VERSION)/promoted
PROMOTED_BUILD_LATEST = latest PROMOTED_BUILD_LATEST = latest
PROMOTED_BUILD_BASEDIR = $(PROMOTED_RE_AREA)/$(PROMOTED_BUILD_LATEST) PROMOTED_BUILD_BASEDIR = $(PROMOTED_RE_AREA)/$(PROMOTED_BUILD_LATEST)
PROMOTED_BUILD_DISTDIR = $(PROMOTED_BUILD_BASEDIR)/dist/$(PLATFORM)-$(ARCH)
PROMOTED_BUILD_BINARIES = $(PROMOTED_BUILD_BASEDIR)/binaries PROMOTED_BUILD_BINARIES = $(PROMOTED_BUILD_BASEDIR)/binaries
# PARALLEL_COMPILE_JOBS: is the number of compiles done in parallel. # PARALLEL_COMPILE_JOBS: is the number of compiles done in parallel.
......
...@@ -1545,10 +1545,49 @@ ifeq ($(ARCH_DATA_MODEL), 32) ...@@ -1545,10 +1545,49 @@ ifeq ($(ARCH_DATA_MODEL), 32)
" and/or check your value of ALT_JDK_DEVTOOLS_DIR, ALT_MOZILLA_HEADERS_PATH, \n" \ " and/or check your value of ALT_JDK_DEVTOOLS_DIR, ALT_MOZILLA_HEADERS_PATH, \n" \
"" >> $(ERROR_FILE) ; \ "" >> $(ERROR_FILE) ; \
fi fi
endif
@#
@# Check for presence of headers required for new Java Plug-In ("plugin2")
@#
@if [ ! -r $(subst \,/,$(MOZILLA_HEADERS_PATH))/plugin2_mozilla_headers/npapi.h ]; then \
$(ECHO) "ERROR: You do not have access to valid Mozilla header files for the new Java Plug-In. \n" \
" Please check your access to \n" \
" $(subst \,/,$(MOZILLA_HEADERS_PATH))/plugin2_mozilla_headers/npapi.h \n" \
" and/or check your value of ALT_JDK_DEVTOOLS_DIR, ALT_MOZILLA_HEADERS_PATH, \n" \
"" >> $(ERROR_FILE) ; \
fi
endif
######################################################
# Make sure Java Kernel VM is accessible
######################################################
sane-kernel-vm:
ifeq ($(PLATFORM), windows)
ifeq ($(ARCH_DATA_MODEL), 32)
@if [ ! -r $(HOTSPOT_KERNEL_PATH)/jvm.dll ]; then \
$(ECHO) "ERROR: Your HOTSPOT_IMPORT_PATH does not include a Kernel VM... \n" \
" $(HOTSPOT_KERNEL_PATH)/jvm.dll \n" \
" Please check the value of ALT_HOTSPOT_IMPORT_PATH. \n" \
>> $(ERROR_FILE) ; \
fi
endif endif
endif endif
######################################################
# SECURITY_BASELINE_131 test
######################################################
security_baseline_131:
ifeq ($(PLATFORM), windows)
@if [ -z "$(SECURITY_BASELINE_131)" ]; then \
$(ECHO) "WARNING: Your SECURITY_BASELINE_131 setting is empty.\n" \
" Setting it to the default value of 1.3.1_20.\n" \
" It is recommended to set SECURITY_BASELINE_131.\n" \
"" >> $(WARNING_FILE) ; \
fi
endif
###################################################### ######################################################
# SECURITY_BASELINE_142 test # SECURITY_BASELINE_142 test
###################################################### ######################################################
...@@ -1575,6 +1614,19 @@ ifeq ($(PLATFORM), windows) ...@@ -1575,6 +1614,19 @@ ifeq ($(PLATFORM), windows)
fi fi
endif endif
######################################################
# SECURITY_BASELINE_160 test
######################################################
security_baseline_160:
ifeq ($(PLATFORM), windows)
@if [ -z "$(SECURITY_BASELINE_160)" ]; then \
$(ECHO) "WARNING: Your SECURITY_BASELINE_160 setting is empty.\n" \
" Setting it to the default value of 1.6.0_11.\n" \
" It is recommended to set SECURITY_BASELINE_160.\n" \
"" >> $(WARNING_FILE) ; \
fi
endif
###################################################### ######################################################
# this should be the last rule in any target's sanity rule. # this should be the last rule in any target's sanity rule.
......
...@@ -64,6 +64,7 @@ FILES_c = \ ...@@ -64,6 +64,7 @@ FILES_c = \
jio.c \ jio.c \
logging.c \ logging.c \
jni_util.c \ jni_util.c \
jni_util_md.c \
jdk_util.c \ jdk_util.c \
jdk_util_md.c \ jdk_util_md.c \
check_version.c \ check_version.c \
......
...@@ -40,6 +40,7 @@ include $(BUILDDIR)/common/Defs.gmk ...@@ -40,6 +40,7 @@ include $(BUILDDIR)/common/Defs.gmk
SERVER_LOCATION = server SERVER_LOCATION = server
CLIENT_LOCATION = client CLIENT_LOCATION = client
KERNEL_LOCATION = kernel
DB_SUFFIX = _db DB_SUFFIX = _db
...@@ -103,6 +104,12 @@ endif ...@@ -103,6 +104,12 @@ endif
ifeq ($(PLATFORM), windows) ifeq ($(PLATFORM), windows)
# Windows vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv Windows # Windows vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv Windows
# Add the Java Kernel VM to the import path, but only on windows 32-bit Windows
ifeq ($(ARCH_DATA_MODEL), 32)
IMPORT_LIST += $(LIB_LOCATION)/$(KERNEL_LOCATION)/$(JVM_NAME) \
$(LIB_LOCATION)/$(KERNEL_LOCATION)/Xusage.txt
endif
IMPORT_LIST += $(MS_RUNTIME_LIBRARIES:%=$(BINDIR)/%) IMPORT_LIST += $(MS_RUNTIME_LIBRARIES:%=$(BINDIR)/%)
# NOTE: These might actually come from BUILDDIR, depends on the settings. # NOTE: These might actually come from BUILDDIR, depends on the settings.
...@@ -119,10 +126,13 @@ IMPORT_LIST += \ ...@@ -119,10 +126,13 @@ IMPORT_LIST += \
$(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMMAP_NAME) \ $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMMAP_NAME) \
$(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMPDB_NAME) $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMPDB_NAME)
# Hotspot client is only available on 32-bit builds # Add .map and .pdb files to the import path for client and kernel VMs.
# These are only available on 32-bit windows builds.
ifeq ($(ARCH_DATA_MODEL), 32) ifeq ($(ARCH_DATA_MODEL), 32)
IMPORT_LIST += $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVMMAP_NAME) \ IMPORT_LIST += $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVMMAP_NAME) \
$(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVMPDB_NAME) $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVMPDB_NAME)
IMPORT_LIST += $(LIB_LOCATION)/$(KERNEL_LOCATION)/$(JVMMAP_NAME) \
$(LIB_LOCATION)/$(KERNEL_LOCATION)/$(JVMPDB_NAME)
endif endif
$(LIBDIR)/$(JVMLIB_NAME): $(HOTSPOT_LIB_PATH)/$(JVMLIB_NAME) $(LIBDIR)/$(JVMLIB_NAME): $(HOTSPOT_LIB_PATH)/$(JVMLIB_NAME)
...@@ -134,6 +144,10 @@ $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVMMAP_NAME): ...@@ -134,6 +144,10 @@ $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVMMAP_NAME):
@$(prep-target) @$(prep-target)
-$(CP) $(HOTSPOT_CLIENT_PATH)/$(JVMMAP_NAME) $@ -$(CP) $(HOTSPOT_CLIENT_PATH)/$(JVMMAP_NAME) $@
$(LIB_LOCATION)/$(KERNEL_LOCATION)/$(JVMMAP_NAME):
@$(prep-target)
-$(CP) $(HOTSPOT_KERNEL_PATH)/$(JVMMAP_NAME) $@
$(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMMAP_NAME): $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMMAP_NAME):
@$(prep-target) @$(prep-target)
-$(CP) $(HOTSPOT_SERVER_PATH)/$(JVMMAP_NAME) $@ -$(CP) $(HOTSPOT_SERVER_PATH)/$(JVMMAP_NAME) $@
...@@ -142,6 +156,10 @@ $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVMPDB_NAME): ...@@ -142,6 +156,10 @@ $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVMPDB_NAME):
@$(prep-target) @$(prep-target)
-$(CP) $(HOTSPOT_CLIENT_PATH)/$(JVMPDB_NAME) $@ -$(CP) $(HOTSPOT_CLIENT_PATH)/$(JVMPDB_NAME) $@
$(LIB_LOCATION)/$(KERNEL_LOCATION)/$(JVMPDB_NAME):
@$(prep-target)
-$(CP) $(HOTSPOT_KERNEL_PATH)/$(JVMPDB_NAME) $@
$(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMPDB_NAME): $(LIB_LOCATION)/$(SERVER_LOCATION)/$(JVMPDB_NAME):
@$(prep-target) @$(prep-target)
-$(CP) $(HOTSPOT_SERVER_PATH)/$(JVMPDB_NAME) $@ -$(CP) $(HOTSPOT_SERVER_PATH)/$(JVMPDB_NAME) $@
...@@ -195,6 +213,9 @@ endif # PLATFORM ...@@ -195,6 +213,9 @@ endif # PLATFORM
$(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVM_NAME): $(HOTSPOT_CLIENT_PATH)/$(JVM_NAME) $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVM_NAME): $(HOTSPOT_CLIENT_PATH)/$(JVM_NAME)
$(install-import-file) $(install-import-file)
$(LIB_LOCATION)/$(KERNEL_LOCATION)/$(JVM_NAME): $(HOTSPOT_KERNEL_PATH)/$(JVM_NAME)
$(install-file)
$(LIB_LOCATION)/$(LIBJSIG_NAME): $(HOTSPOT_SERVER_PATH)/$(LIBJSIG_NAME) $(LIB_LOCATION)/$(LIBJSIG_NAME): $(HOTSPOT_SERVER_PATH)/$(LIBJSIG_NAME)
$(install-import-file) $(install-import-file)
...@@ -224,6 +245,9 @@ $(LIB_LOCATION)/$(SERVER_LOCATION)/Xusage.txt : $(HOTSPOT_SERVER_PATH)/Xusage.tx ...@@ -224,6 +245,9 @@ $(LIB_LOCATION)/$(SERVER_LOCATION)/Xusage.txt : $(HOTSPOT_SERVER_PATH)/Xusage.tx
$(LIB_LOCATION)/$(CLIENT_LOCATION)/Xusage.txt : $(HOTSPOT_CLIENT_PATH)/Xusage.txt $(LIB_LOCATION)/$(CLIENT_LOCATION)/Xusage.txt : $(HOTSPOT_CLIENT_PATH)/Xusage.txt
$(install-import-file) $(install-import-file)
$(LIB_LOCATION)/$(KERNEL_LOCATION)/Xusage.txt : $(HOTSPOT_KERNEL_PATH)/Xusage.txt
$(install-file)
ifeq ($(INCLUDE_SA), true) ifeq ($(INCLUDE_SA), true)
# The Serviceability Agent is built in the Hotspot workspace. # The Serviceability Agent is built in the Hotspot workspace.
# It contains two files: # It contains two files:
......
...@@ -33,6 +33,12 @@ PRODUCT = jpda ...@@ -33,6 +33,12 @@ PRODUCT = jpda
PROGRAM = jdb PROGRAM = jdb
include $(BUILDDIR)/common/Defs.gmk include $(BUILDDIR)/common/Defs.gmk
# This program must contain a manifest that defines the execution level
# needed to follow standard Vista User Access Control Guidelines
# This must be set before Program.gmk is included
#
BUILD_MANIFEST=true
# #
# Java Files to compile are found automatically. # Java Files to compile are found automatically.
# #
......
...@@ -58,7 +58,7 @@ ifdef OPENJDK ...@@ -58,7 +58,7 @@ ifdef OPENJDK
else else
RENDER_SUBDIR = dcpr RENDER_SUBDIR = dcpr
endif endif
SUBDIRS = jar security javazic misc net audio $(RENDER_SUBDIR) image \ SUBDIRS = jar security javazic misc jkernel net audio $(RENDER_SUBDIR) image \
awt splashscreen $(XAWT_SUBDIR) \ awt splashscreen $(XAWT_SUBDIR) \
$(HEADLESS_SUBDIR) $(DGA_SUBDIR) \ $(HEADLESS_SUBDIR) $(DGA_SUBDIR) \
font jpeg cmm applet rmi beans $(JDBC_SUBDIR) \ font jpeg cmm applet rmi beans $(JDBC_SUBDIR) \
......
...@@ -32,6 +32,12 @@ PACKAGE = sun.applet ...@@ -32,6 +32,12 @@ PACKAGE = sun.applet
PRODUCT = sun PRODUCT = sun
include $(BUILDDIR)/common/Defs.gmk include $(BUILDDIR)/common/Defs.gmk
# This program must contain a manifest that defines the execution level
# needed to follow standard Vista User Access Control Guidelines
# This must be set before Program.gmk is included
#
BUILD_MANIFEST=true
# #
# Files to compile. # Files to compile.
# #
......
...@@ -32,6 +32,13 @@ PACKAGE = sun.tools ...@@ -32,6 +32,13 @@ PACKAGE = sun.tools
PRODUCT = sun PRODUCT = sun
include $(BUILDDIR)/common/Defs.gmk include $(BUILDDIR)/common/Defs.gmk
# This program must contain a manifest that defines the execution level
# needed to follow standard Vista User Access Control Guidelines
# This must be set before Program.gmk is included
#
BUILD_MANIFEST=true
# #
# Files # Files
# #
......
...@@ -54,9 +54,9 @@ Link America/Los_Angeles PST ...@@ -54,9 +54,9 @@ Link America/Los_Angeles PST
Link Pacific/Guadalcanal SST Link Pacific/Guadalcanal SST
Link Asia/Saigon VST Link Asia/Saigon VST
# The follwong link is required to generate J2SE 1.2.x and 1.3.x # The follwong link is required to generate JDK 1.2.x and 1.3.x
# compatible zones. In the Olson public source, MET is defined as # compatible zones. In the Olson public source, MET is defined as
# GMT+1:00 with the C-Eur rules. In J2SE, MET is defined as an alias # GMT+1:00 with the C-Eur rules. In JDK, MET is defined as an alias
# of Asia/Tehran. This line must be removed if a full set of Olson # of Asia/Tehran. This line must be removed if a full set of Olson
# zones is generated. Otherwise, MET appears twice in the # zones is generated. Otherwise, MET appears twice in the
# ZoneInfoMappings.IDs table. # ZoneInfoMappings.IDs table.
......
...@@ -32,6 +32,13 @@ PACKAGE = sun.tools.jconsole ...@@ -32,6 +32,13 @@ PACKAGE = sun.tools.jconsole
PRODUCT = sun PRODUCT = sun
include $(BUILDDIR)/common/Defs.gmk include $(BUILDDIR)/common/Defs.gmk
# This program must contain a manifest that defines the execution level
# needed to follow standard Vista User Access Control Guidelines
# This must be set before Program.gmk is included
#
BUILD_MANIFEST=true
JARFILE = $(LIBDIR)/jconsole.jar JARFILE = $(LIBDIR)/jconsole.jar
OTHER_JAVACFLAGS += -encoding iso8859-1 OTHER_JAVACFLAGS += -encoding iso8859-1
......
#
# Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Sun designates this
# particular file as subject to the "Classpath" exception as provided
# by Sun in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
FILES_cpp = \
stdafx.cpp \
kernel.cpp \
DownloadDialog.cpp \
DownloadHelper.cpp \
DownloadHelper.cpp
FILES_rc = kernel.rc
# FILES_export definitions for Win32
FILES_export = \
sun/jkernel/DownloadManager.java \
sun/jkernel/Mutex.java \
sun/jkernel/Bundle.java \
sun/jkernel/BackgroundDownloader.java \
#
# Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Sun designates this
# particular file as subject to the "Classpath" exception as provided
# by Sun in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
FILES_java = \
$(TARGDIR)sun/jkernel/BackgroundDownloader.java \
$(TARGDIR)sun/jkernel/Bundle.java \
$(TARGDIR)sun/jkernel/ByteArrayToFromHexDigits.java \
$(TARGDIR)sun/jkernel/BundleCheck.java \
$(TARGDIR)sun/jkernel/DownloadManager.java \
$(TARGDIR)sun/jkernel/Mutex.java \
$(TARGDIR)sun/jkernel/StandaloneByteArrayAccess.java \
$(TARGDIR)sun/jkernel/StandaloneMessageDigest.java \
$(TARGDIR)sun/jkernel/StandaloneSHA.java \
FILES_export = \
sun/jkernel/DownloadManager.java \
sun/jkernel/Mutex.java \
sun/jkernel/Bundle.java \
sun/jkernel/BackgroundDownloader.java
#
# Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Sun designates this
# particular file as subject to the "Classpath" exception as provided
# by Sun in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
BUILDDIR = ../..
PACKAGE = sun.jkernel
LIBRARY = jkernel
PRODUCT = sun
include $(BUILDDIR)/common/Defs.gmk
#
# Use highest optimization level
#
_OPT = $(CC_HIGHEST_OPT)
# This re-directs all the class files to a separate location
CLASSDESTDIR = $(TEMPDIR)/classes
#
# Java source files
#
include FILES_java.gmk
AUTO_FILES_JAVA_DIRS = sun/jkernel
LOCALE_SUFFIXES = $(JDK_LOCALES)
#
# Native source files
#
ifeq ($(ARCH_DATA_MODEL), 32)
ifeq ($(PLATFORM), windows)
include FILES_c_windows.gmk
vpath %.cpp $(PLATFORM_SRC)/native/sun/jkernel
VERSIONINFO_RESOURCE = $(PLATFORM_SRC)/native/sun/jkernel/kernel.rc
LDLIBS += urlmon.lib wininet.lib shlwapi.lib version.lib comctl32.lib gdi32.lib -def:$(PLATFORM_SRC)/native/sun/jkernel/kernel.def
include $(BUILDDIR)/common/Library.gmk
endif
endif
#
# Resources
#
include $(TOPDIR)/make/common/internal/Resources.gmk
#
# Rules
#
include $(BUILDDIR)/common/Classes.gmk
# If extra compression is going to be available in the deploy build enable
# its use here by defining the JRE-relative pathname of the shared library
ifeq ($(PLATFORM), windows)
ifdef EXTRA_COMP_INSTALL_PATH
CPPFLAGS += -DEXTRA_COMP_INSTALL_PATH=$(EXTRA_COMP_INSTALL_PATH)
endif
endif
...@@ -33,6 +33,13 @@ PRODUCT = sun ...@@ -33,6 +33,13 @@ PRODUCT = sun
OTHER_JAVACFLAGS += -Xlint:serial -Werror OTHER_JAVACFLAGS += -Xlint:serial -Werror
include $(BUILDDIR)/common/Defs.gmk include $(BUILDDIR)/common/Defs.gmk
# This program must contain a manifest that defines the execution level
# needed to follow standard Vista User Access Control Guidelines
# This must be set before Program.gmk is included
#
BUILD_MANIFEST=true
# #
# Files # Files
# #
......
...@@ -32,6 +32,13 @@ PACKAGE = sun.rmi.rmic ...@@ -32,6 +32,13 @@ PACKAGE = sun.rmi.rmic
PRODUCT = sun PRODUCT = sun
include $(BUILDDIR)/common/Defs.gmk include $(BUILDDIR)/common/Defs.gmk
#
# This program must contain a manifest that defines the execution level
# needed to follow standard Vista User Access Control Guidelines
# This must be set before Program.gmk is included
#
BUILD_MANIFEST=true
# #
# Files # Files
# #
......
...@@ -32,6 +32,14 @@ PACKAGE = sun.tools.serialver ...@@ -32,6 +32,14 @@ PACKAGE = sun.tools.serialver
PRODUCT = sun PRODUCT = sun
include $(BUILDDIR)/common/Defs.gmk include $(BUILDDIR)/common/Defs.gmk
#
# This program must contain a manifest that defines the execution level
# needed to follow standard Vista User Access Control Guidelines
# This must be set before Program.gmk is included
#
BUILD_MANIFEST=true
# #
# Files # Files
# #
......
...@@ -1823,10 +1823,18 @@ public class ICC_Profile implements Serializable { ...@@ -1823,10 +1823,18 @@ public class ICC_Profile implements Serializable {
} }
if (!f.isFile()) { /* try the directory of built-in profiles */ if (!f.isFile()) { /* try the directory of built-in profiles */
dir = System.getProperty("java.home") + dir = System.getProperty("java.home") +
File.separatorChar + "lib" + File.separatorChar + "cmm"; File.separatorChar + "lib" + File.separatorChar + "cmm";
fullPath = dir + File.separatorChar + fileName; fullPath = dir + File.separatorChar + fileName;
f = new File(fullPath); f = new File(fullPath);
if (!f.isFile()) {
//make sure file was installed in the kernel mode
try {
//kernel uses platform independent paths =>
// should not use platform separator char
sun.jkernel.DownloadManager.downloadFile("lib/cmm/"+fileName);
} catch (IOException ioe) {}
}
} }
if (f.isFile()) { if (f.isFile()) {
......
...@@ -58,6 +58,7 @@ import sun.misc.URLClassPath; ...@@ -58,6 +58,7 @@ import sun.misc.URLClassPath;
import sun.misc.VM; import sun.misc.VM;
import sun.reflect.Reflection; import sun.reflect.Reflection;
import sun.security.util.SecurityConstants; import sun.security.util.SecurityConstants;
import sun.jkernel.DownloadManager;
/** /**
* A class loader is an object that is responsible for loading classes. The * A class loader is an object that is responsible for loading classes. The
...@@ -1280,6 +1281,21 @@ public abstract class ClassLoader { ...@@ -1280,6 +1281,21 @@ public abstract class ClassLoader {
* Find resources from the VM's built-in classloader. * Find resources from the VM's built-in classloader.
*/ */
private static URL getBootstrapResource(String name) { private static URL getBootstrapResource(String name) {
try {
// If this is a known JRE resource, ensure that its bundle is
// downloaded. If it isn't known, we just ignore the download
// failure and check to see if we can find the resource anyway
// (which is possible if the boot class path has been modified).
if (sun.misc.VM.isBootedKernelVM()) {
sun.jkernel.DownloadManager.getBootClassPathEntryForResource(
name);
}
} catch (NoClassDefFoundError e) {
// This happens while Java itself is being compiled; DownloadManager
// isn't accessible when this code is first invoked. It isn't an
// issue, as if we can't find DownloadManager, we can safely assume
// that additional code is not available for download.
}
URLClassPath ucp = getBootstrapClassPath(); URLClassPath ucp = getBootstrapClassPath();
Resource res = ucp.getResource(name); Resource res = ucp.getResource(name);
return res != null ? res.getURL() : null; return res != null ? res.getURL() : null;
...@@ -1305,13 +1321,9 @@ public abstract class ClassLoader { ...@@ -1305,13 +1321,9 @@ public abstract class ClassLoader {
// Returns the URLClassPath that is used for finding system resources. // Returns the URLClassPath that is used for finding system resources.
static URLClassPath getBootstrapClassPath() { static URLClassPath getBootstrapClassPath() {
if (bootstrapClassPath == null) { return sun.misc.Launcher.getBootstrapClassPath();
bootstrapClassPath = sun.misc.Launcher.getBootstrapClassPath();
}
return bootstrapClassPath;
} }
private static URLClassPath bootstrapClassPath;
/** /**
* Returns an input stream for reading the specified resource. * Returns an input stream for reading the specified resource.
...@@ -1800,6 +1812,24 @@ public abstract class ClassLoader { ...@@ -1800,6 +1812,24 @@ public abstract class ClassLoader {
// Invoked in the java.lang.Runtime class to implement load and loadLibrary. // Invoked in the java.lang.Runtime class to implement load and loadLibrary.
static void loadLibrary(Class fromClass, String name, static void loadLibrary(Class fromClass, String name,
boolean isAbsolute) { boolean isAbsolute) {
try {
if (VM.isBootedKernelVM() && !DownloadManager.isJREComplete() &&
!DownloadManager.isCurrentThreadDownloading()) {
DownloadManager.downloadFile("bin/" +
System.mapLibraryName(name));
// it doesn't matter if the downloadFile call returns false --
// it probably just means that this is a user library, as
// opposed to a JRE library
}
} catch (IOException e) {
throw new UnsatisfiedLinkError("Error downloading library " +
name + ": " + e);
} catch (NoClassDefFoundError e) {
// This happens while Java itself is being compiled; DownloadManager
// isn't accessible when this code is first invoked. It isn't an
// issue, as if we can't find DownloadManager, we can safely assume
// that additional code is not available for download.
}
ClassLoader loader = ClassLoader loader =
(fromClass == null) ? null : fromClass.getClassLoader(); (fromClass == null) ? null : fromClass.getClassLoader();
if (sys_paths == null) { if (sys_paths == null) {
......
...@@ -1106,12 +1106,22 @@ public final class System { ...@@ -1106,12 +1106,22 @@ public final class System {
initProperties(props); initProperties(props);
sun.misc.Version.init(); sun.misc.Version.init();
// Workaround until DownloadManager initialization is revisited.
// Make JavaLangAccess available early enough for internal
// Shutdown hooks to be registered
setJavaLangAccess();
// Gets and removes system properties that configure the Integer // Gets and removes system properties that configure the Integer
// cache used to support the object identity semantics of autoboxing. // cache used to support the object identity semantics of autoboxing.
// At this time, the size of the cache may be controlled by the // At this time, the size of the cache may be controlled by the
// -XX:AutoBoxCacheMax=<size> option. // vm option -XX:AutoBoxCacheMax=<size>.
Integer.getAndRemoveCacheProperties(); Integer.getAndRemoveCacheProperties();
// Load the zip library now in order to keep java.util.zip.ZipFile
// from trying to use itself to load this library later.
loadLibrary("zip");
FileInputStream fdIn = new FileInputStream(FileDescriptor.in); FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out); FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err); FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
...@@ -1119,10 +1129,6 @@ public final class System { ...@@ -1119,10 +1129,6 @@ public final class System {
setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true)); setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true)); setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true));
// Load the zip library now in order to keep java.util.zip.ZipFile
// from trying to use itself to load this library later.
loadLibrary("zip");
// Setup Java signal handlers for HUP, TERM, and INT (where available). // Setup Java signal handlers for HUP, TERM, and INT (where available).
Terminator.setup(); Terminator.setup();
...@@ -1152,7 +1158,9 @@ public final class System { ...@@ -1152,7 +1158,9 @@ public final class System {
// way as other threads; we must do it ourselves here. // way as other threads; we must do it ourselves here.
Thread current = Thread.currentThread(); Thread current = Thread.currentThread();
current.getThreadGroup().add(current); current.getThreadGroup().add(current);
}
private static void setJavaLangAccess() {
// Allow privileged classes outside of java.lang // Allow privileged classes outside of java.lang
sun.misc.SharedSecrets.setJavaLangAccess(new sun.misc.JavaLangAccess(){ sun.misc.SharedSecrets.setJavaLangAccess(new sun.misc.JavaLangAccess(){
public sun.reflect.ConstantPool getConstantPool(Class klass) { public sun.reflect.ConstantPool getConstantPool(Class klass) {
......
...@@ -109,7 +109,15 @@ class ZipEntry implements ZipConstants, Cloneable { ...@@ -109,7 +109,15 @@ class ZipEntry implements ZipConstants, Cloneable {
* @see #getTime() * @see #getTime()
*/ */
public void setTime(long time) { public void setTime(long time) {
this.time = javaToDosTime(time); // fix for bug 6625963: we bypass time calculations while Kernel is
// downloading bundles, since they aren't necessary and would cause
// the Kernel core to depend upon the (very large) time zone data
if (sun.misc.VM.isBootedKernelVM() &&
sun.jkernel.DownloadManager.isCurrentThreadDownloading()) {
this.time = sun.jkernel.DownloadManager.KERNEL_STATIC_MODTIME;
} else {
this.time = javaToDosTime(time);
}
} }
/** /**
...@@ -245,10 +253,14 @@ class ZipEntry implements ZipConstants, Cloneable { ...@@ -245,10 +253,14 @@ class ZipEntry implements ZipConstants, Cloneable {
* the first 0xFFFF bytes are output to the ZIP file entry. * the first 0xFFFF bytes are output to the ZIP file entry.
* *
* @param comment the comment string * @param comment the comment string
* * @exception IllegalArgumentException if the length of the specified
* comment string is greater than 0xFFFF bytes
* @see #getComment() * @see #getComment()
*/ */
public void setComment(String comment) { public void setComment(String comment) {
if (comment != null && comment.length() > 0xffff) {
throw new IllegalArgumentException("invalid entry comment length");
}
this.comment = comment; this.comment = comment;
} }
......
...@@ -69,6 +69,7 @@ public class AppletClassLoader extends URLClassLoader { ...@@ -69,6 +69,7 @@ public class AppletClassLoader extends URLClassLoader {
private final Object grabReleaseSynchronizer = new Object(); private final Object grabReleaseSynchronizer = new Object();
private boolean codebaseLookup = true; private boolean codebaseLookup = true;
private volatile boolean allowRecursiveDirectoryRead = true;
/* /*
* Creates a new AppletClassLoader for the specified base URL. * Creates a new AppletClassLoader for the specified base URL.
...@@ -81,6 +82,11 @@ public class AppletClassLoader extends URLClassLoader { ...@@ -81,6 +82,11 @@ public class AppletClassLoader extends URLClassLoader {
acc = AccessController.getContext(); acc = AccessController.getContext();
} }
public void disableRecursiveDirectoryRead() {
allowRecursiveDirectoryRead = false;
}
/** /**
* Set the codebase lookup flag. * Set the codebase lookup flag.
*/ */
...@@ -188,7 +194,21 @@ public class AppletClassLoader extends URLClassLoader { ...@@ -188,7 +194,21 @@ public class AppletClassLoader extends URLClassLoader {
byte[] b = (byte[]) AccessController.doPrivileged( byte[] b = (byte[]) AccessController.doPrivileged(
new PrivilegedExceptionAction() { new PrivilegedExceptionAction() {
public Object run() throws IOException { public Object run() throws IOException {
return getBytes(new URL(base, path)); try {
URL finalURL = new URL(base, path);
// Make sure the codebase won't be modified
if (base.getProtocol().equals(finalURL.getProtocol()) &&
base.getHost().equals(finalURL.getHost()) &&
base.getPort() == finalURL.getPort()) {
return getBytes(finalURL);
}
else {
return null;
}
} catch (Exception e) {
return null;
}
} }
}, acc); }, acc);
...@@ -243,51 +263,48 @@ public class AppletClassLoader extends URLClassLoader { ...@@ -243,51 +263,48 @@ public class AppletClassLoader extends URLClassLoader {
} }
if (path != null) { if (path != null) {
final String rawPath = path;
if (!path.endsWith(File.separator)) { if (!path.endsWith(File.separator)) {
int endIndex = path.lastIndexOf(File.separatorChar); int endIndex = path.lastIndexOf(File.separatorChar);
if (endIndex != -1) { if (endIndex != -1) {
path = path.substring(0, endIndex+1) + "-"; path = path.substring(0, endIndex + 1) + "-";
perms.add(new FilePermission(path, perms.add(new FilePermission(path,
SecurityConstants.FILE_READ_ACTION)); SecurityConstants.FILE_READ_ACTION));
} }
} }
perms.add(new SocketPermission("localhost", final File f = new File(rawPath);
SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION)); final boolean isDirectory = f.isDirectory();
AccessController.doPrivileged(new PrivilegedAction() { // grant codebase recursive read permission
public Object run() { // this should only be granted to non-UNC file URL codebase and
try { // the codesource path must either be a directory, or a file
String host = InetAddress.getLocalHost().getHostName(); // that ends with .jar or .zip
perms.add(new SocketPermission(host, if (allowRecursiveDirectoryRead && (isDirectory ||
SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION)); rawPath.toLowerCase().endsWith(".jar") ||
} catch (UnknownHostException uhe) { rawPath.toLowerCase().endsWith(".zip"))) {
}
return null;
}
});
Permission bperm; Permission bperm;
try { try {
bperm = base.openConnection().getPermission(); bperm = base.openConnection().getPermission();
} catch (java.io.IOException ioe) { } catch (java.io.IOException ioe) {
bperm = null; bperm = null;
}
if (bperm instanceof FilePermission) {
String bpath = bperm.getName();
if (bpath.endsWith(File.separator)) {
bpath += "-";
} }
perms.add(new FilePermission(bpath, if (bperm instanceof FilePermission) {
SecurityConstants.FILE_READ_ACTION)); String bpath = bperm.getName();
} else if ((bperm == null) && (base.getProtocol().equals("file"))) { if (bpath.endsWith(File.separator)) {
String bpath = base.getFile().replace('/', File.separatorChar); bpath += "-";
bpath = ParseUtil.decode(bpath); }
if (bpath.endsWith(File.separator)) { perms.add(new FilePermission(bpath,
bpath += "-"; SecurityConstants.FILE_READ_ACTION));
} else if ((bperm == null) && (base.getProtocol().equals("file"))) {
String bpath = base.getFile().replace('/', File.separatorChar);
bpath = ParseUtil.decode(bpath);
if (bpath.endsWith(File.separator)) {
bpath += "-";
}
perms.add(new FilePermission(bpath, SecurityConstants.FILE_READ_ACTION));
} }
perms.add(new FilePermission(bpath, SecurityConstants.FILE_READ_ACTION));
}
}
} }
return perms; return perms;
} }
...@@ -702,7 +719,7 @@ public class AppletClassLoader extends URLClassLoader { ...@@ -702,7 +719,7 @@ public class AppletClassLoader extends URLClassLoader {
* Grab this AppletClassLoader and its ThreadGroup/AppContext, so they * Grab this AppletClassLoader and its ThreadGroup/AppContext, so they
* won't be destroyed. * won't be destroyed.
*/ */
void grab() { public void grab() {
synchronized(grabReleaseSynchronizer) { synchronized(grabReleaseSynchronizer) {
usageCount++; usageCount++;
} }
...@@ -740,11 +757,7 @@ public class AppletClassLoader extends URLClassLoader { ...@@ -740,11 +757,7 @@ public class AppletClassLoader extends URLClassLoader {
--usageCount; --usageCount;
} else { } else {
synchronized(threadGroupSynchronizer) { synchronized(threadGroupSynchronizer) {
// Store app context in temp variable tempAppContext = resetAppContext();
tempAppContext = appContext;
usageCount = 0;
appContext = null;
threadGroup = null;
} }
} }
} }
...@@ -758,6 +771,29 @@ public class AppletClassLoader extends URLClassLoader { ...@@ -758,6 +771,29 @@ public class AppletClassLoader extends URLClassLoader {
} }
} }
/*
* reset classloader's AppContext and ThreadGroup
* This method is for subclass PluginClassLoader to
* reset superclass's AppContext and ThreadGroup but do
* not dispose the AppContext. PluginClassLoader does not
* use UsageCount to decide whether to dispose AppContext
*
* @return previous AppContext
*/
protected AppContext resetAppContext() {
AppContext tempAppContext = null;
synchronized(threadGroupSynchronizer) {
// Store app context in temp variable
tempAppContext = appContext;
usageCount = 0;
appContext = null;
threadGroup = null;
}
return tempAppContext;
}
// Hash map to store applet compatibility info // Hash map to store applet compatibility info
private HashMap jdk11AppletInfo = new HashMap(); private HashMap jdk11AppletInfo = new HashMap();
private HashMap jdk12AppletInfo = new HashMap(); private HashMap jdk12AppletInfo = new HashMap();
......
...@@ -80,7 +80,7 @@ abstract class AppletPanel extends Panel implements AppletStub, Runnable { ...@@ -80,7 +80,7 @@ abstract class AppletPanel extends Panel implements AppletStub, Runnable {
/** /**
* The classloader for the applet. * The classloader for the applet.
*/ */
AppletClassLoader loader; protected AppletClassLoader loader;
/* applet event ids */ /* applet event ids */
public final static int APPLET_DISPOSE = 0; public final static int APPLET_DISPOSE = 0;
...@@ -116,7 +116,7 @@ abstract class AppletPanel extends Panel implements AppletStub, Runnable { ...@@ -116,7 +116,7 @@ abstract class AppletPanel extends Panel implements AppletStub, Runnable {
/** /**
* The thread for the applet. * The thread for the applet.
*/ */
Thread handler; protected Thread handler;
/** /**
......
/*
* Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.jkernel;
import java.io.*;
/**
* Invoked by DownloadManager to begin (in a new JRE) the process of downloading
* all remaining JRE components in the background. A mutex is used to ensure
* that only one BackgroundDownloader can be active at a time.
*
*/
public class BackgroundDownloader {
public static final String BACKGROUND_DOWNLOAD_PROPERTY = "kernel.background.download";
// relative to the bundle directory
public static final String PID_PATH = "tmp" + File.separator + "background.pid";
// Time to wait before beginning to download components. Gives the JRE
// which spawned this one a chance to get its downloads going.
private static final int WAIT_TIME = 10000;
private static Mutex backgroundMutex;
static synchronized Mutex getBackgroundMutex() {
if (backgroundMutex == null)
backgroundMutex = Mutex.create(DownloadManager.MUTEX_PREFIX + "background");
return backgroundMutex;
}
private static void doBackgroundDownloads() {
if (DownloadManager.isJREComplete())
return;
if (getBackgroundMutex().acquire(0)) { // give up and exit immediately if we can't acquire mutex
try {
writePid();
Thread.sleep(WAIT_TIME);
DownloadManager.doBackgroundDownloads(false);
DownloadManager.performCompletionIfNeeded();
}
catch (InterruptedException e) {
}
finally {
getBackgroundMutex().release();
}
}
else {
System.err.println("Unable to acquire background download mutex.");
System.exit(1);
}
}
/**
* Writes the current process ID to a file, so that the uninstaller can
* find and kill this process if needed.
*/
private static void writePid() {
try {
File pid = new File(DownloadManager.getBundlePath(), PID_PATH);
pid.getParentFile().mkdirs();
PrintStream out = new PrintStream(new FileOutputStream(pid));
pid.deleteOnExit();
out.println(DownloadManager.getCurrentProcessId());
out.close();
}
catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
}
/**
* Reads from an InputStream until exhausted, writing all data to the
* specified OutputStream.
*/
private static void send(InputStream in, OutputStream out)
throws IOException {
int c;
byte[] buffer = new byte[2048];
while ((c = in.read(buffer)) > 0)
out.write(buffer, 0, c);
}
/*
* Returns the value of the BACKGROUND_DOWNLOAD_PROPERTY.
* Checks if system property has been set first
* then checks if registry key to disable background download
* has been set.
*/
public static boolean getBackgroundDownloadProperty(){
/*
* Check registry key value
*/
boolean bgDownloadEnabled = getBackgroundDownloadKey();
/*
* Check system property - it should override the registry
* key value.
*/
if (System.getProperty(BACKGROUND_DOWNLOAD_PROPERTY) != null){
bgDownloadEnabled = Boolean.valueOf(
System.getProperty(BACKGROUND_DOWNLOAD_PROPERTY));
}
return bgDownloadEnabled;
}
// This method is to retrieve the value of registry key
// that disables background download.
static native boolean getBackgroundDownloadKey();
static void startBackgroundDownloads() {
if (!getBackgroundDownloadProperty()){
// If getBackgroundDownloadProperty() returns false
// we're doing the downloads from this VM; we don't want to
// spawn another one
return;
}
// if System.err isn't initialized yet, it means the charsets aren't
// available yet and we're going to run into trouble down below. Wait
// until it's ready.
while (System.err == null) {
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
return;
}
}
try {
String args = "-D" + BACKGROUND_DOWNLOAD_PROPERTY + "=false -Xmx256m";
String backgroundDownloadURL = DownloadManager.getBaseDownloadURL();
// only set KERNEL_DOWNLOAD_URL_PROPERTY if we override
// the default download url
if (backgroundDownloadURL != null &&
backgroundDownloadURL.equals(
DownloadManager.DEFAULT_DOWNLOAD_URL) == false) {
args += " -D" + DownloadManager.KERNEL_DOWNLOAD_URL_PROPERTY +
"=" + backgroundDownloadURL;
};
args += " sun.jkernel.BackgroundDownloader";
final Process jvm = Runtime.getRuntime().exec("\"" + new File(System.getProperty("java.home"), "bin" +
File.separator + "java.exe") + "\" " + args);
Thread outputReader = new Thread("kernelOutputReader") {
public void run() {
try {
InputStream in = jvm.getInputStream();
send(in, new PrintStream(new ByteArrayOutputStream()));
}
catch (IOException e) {
e.printStackTrace();
}
}
};
outputReader.setDaemon(true);
outputReader.start();
Thread errorReader = new Thread("kernelErrorReader") {
public void run() {
try {
InputStream in = jvm.getErrorStream();
send(in, new PrintStream(new ByteArrayOutputStream()));
}
catch (IOException e) {
e.printStackTrace();
}
}
};
errorReader.setDaemon(true);
errorReader.start();
}
catch (Exception e) {
e.printStackTrace();
// TODO: error handling
}
}
public static void main(String[] arg) {
doBackgroundDownloads();
}
}
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.jkernel;
import java.io.*;
import java.net.HttpRetryException;
import java.util.*;
import java.util.concurrent.*;
import java.util.jar.*;
import java.util.zip.GZIPInputStream;
/**
* Represents a bundle which may or may not currently be installed.
*
*@author Ethan Nicholas
*/
public class Bundle {
static {
if (!DownloadManager.jkernelLibLoaded) {
// This code can be invoked directly by the deploy build.
System.loadLibrary("jkernel");
}
}
/**
* Compress file sourcePath with "extra" algorithm (e.g. 7-Zip LZMA)
* if available, put the uncompressed data into file destPath and
* return true. If not available return false and do nothing with destPath.
*
* @param srcPath path to existing uncompressed file
* @param destPath path for the compressed file to be created
* @returns true if extra algorithm used, false if not
* @throws IOException if the extra compression code should be available
* but cannot be located or linked to, the destination file already
* exists or cannot be opened for writing, or the compression fails
*/
public static native boolean extraCompress(String srcPath,
String destPath) throws IOException;
/**
* Decompress file sourcePath with "extra" algorithm (e.g. 7-Zip LZMA)
* if available, put the uncompressed data into file destPath and
* return true. If not available return false and do nothing with
* destPath.
* @param srcPath path to existing compressed file
* @param destPath path to uncompressed file to be created
* @returns true if extra algorithm used, false if not
* @throws IOException if the extra uncompression code should be available
* but cannot be located or linked to, the destination file already
* exists or cannot be opened for writing, or the uncompression fails
*/
public static native boolean extraUncompress(String srcPath,
String destPath) throws IOException;
private static final String BUNDLE_JAR_ENTRY_NAME = "classes.jar";
/** The bundle is not present. */
protected static final int NOT_DOWNLOADED = 0;
/**
* The bundle is in the download queue but has not finished downloading.
*/
protected static final int QUEUED = 1;
/** The bundle has finished downloading but is not installed. */
protected static final int DOWNLOADED = 2;
/** The bundle is fully installed and functional. */
protected static final int INSTALLED = 3;
/** Thread pool used to manage dependency downloads. */
private static ExecutorService threadPool;
/** Size of thread pool. */
static final int THREADS;
static {
String downloads = System.getProperty(
DownloadManager.KERNEL_SIMULTANEOUS_DOWNLOADS_PROPERTY);
if (downloads != null)
THREADS = Integer.parseInt(downloads.trim());
else
THREADS = 1;
}
/** Mutex used to safely access receipts file. */
private static Mutex receiptsMutex;
/** Maps bundle names to known bundle instances. */
private static Map<String, Bundle> bundles =
new HashMap<String, Bundle>();
/** Contains the names of currently-installed bundles. */
static Set<String> receipts = new HashSet<String>();
private static int bytesDownloaded;
/** Path where bundle receipts are written. */
private static File receiptPath = new File(DownloadManager.getBundlePath(),
"receipts");
/** The size of the receipts file the last time we saw it. */
private static int receiptsSize;
/** The bundle name, e.g. "java_awt". */
private String name;
/** The path to which we are saving the downloaded bundle file. */
private File localPath;
/**
* The path of the extracted JAR file containing the bundle's classes.
*/
private File jarPath;
// for vista IE7 protected mode
private File lowJarPath;
private File lowJavaPath = null;
/** The current state (DOWNLOADED, INSTALLED, etc.). */
protected int state;
/**
* True if we should delete the downloaded bundle after installing it.
*/
protected boolean deleteOnInstall = true;
private static Mutex getReceiptsMutex() {
if (receiptsMutex == null)
receiptsMutex = Mutex.create(DownloadManager.MUTEX_PREFIX +
"receipts");
return receiptsMutex;
}
/**
* Reads the receipts file in order to seed the list of currently
* installed bundles.
*/
static synchronized void loadReceipts() {
getReceiptsMutex().acquire();
try {
if (receiptPath.exists()) {
int size = (int) receiptPath.length();
if (size != receiptsSize) { // ensure that it has actually
// been modified
DataInputStream in = null;
try {
receipts.clear();
for (String bundleName : DownloadManager.getBundleNames()) {
if ("true".equals(DownloadManager.getBundleProperty(bundleName,
DownloadManager.INSTALL_PROPERTY)))
receipts.add(bundleName);
}
if (receiptPath.exists()) {
in = new DataInputStream(new BufferedInputStream(
new FileInputStream(receiptPath)));
String line;
while ((line = in.readLine()) != null) {
receipts.add(line.trim());
}
}
receiptsSize = size;
}
catch (IOException e) {
DownloadManager.log(e);
// safe to continue, as the worst that happens is
// we re-download existing bundles
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ioe) {
DownloadManager.log(ioe);
}
}
}
}
}
}
finally {
getReceiptsMutex().release();
}
}
/** Returns the bundle corresponding to the specified name. */
public static synchronized Bundle getBundle(String bundleId)
throws IOException {
Bundle result =(Bundle) bundles.get(bundleId);
if (result == null && (bundleId.equals("merged") ||
Arrays.asList(DownloadManager.getBundleNames()).contains(bundleId))) {
result = new Bundle();
result.name = bundleId;
if (DownloadManager.isWindowsVista()) {
result.localPath =
new File(DownloadManager.getLocalLowTempBundlePath(),
bundleId + ".zip");
result.lowJavaPath = new File(
DownloadManager.getLocalLowKernelJava() + bundleId);
} else {
result.localPath = new File(DownloadManager.getBundlePath(),
bundleId + ".zip");
}
String jarPath = DownloadManager.getBundleProperty(bundleId,
DownloadManager.JAR_PATH_PROPERTY);
if (jarPath != null) {
if (DownloadManager.isWindowsVista()) {
result.lowJarPath = new File(
DownloadManager.getLocalLowKernelJava() + bundleId,
jarPath);
}
result.jarPath = new File(DownloadManager.JAVA_HOME,
jarPath);
} else {
if (DownloadManager.isWindowsVista()) {
result.lowJarPath = new File(
DownloadManager.getLocalLowKernelJava() + bundleId +
"\\lib\\bundles",
bundleId + ".jar");
}
result.jarPath = new File(DownloadManager.getBundlePath(),
bundleId + ".jar");
}
bundles.put(bundleId, result);
}
return result;
}
/**
* Returns the name of this bundle. The name is typically defined by
* the bundles.xml file.
*/
public String getName() {
return name;
}
/**
* Sets the name of this bundle.
*/
public void setName(String name) {
this.name = name;
}
/**
* Returns the path to the bundle file on the local filesystem. The file
* will only exist if the bundle has already been downloaded; otherwise
* it will be created when download() is called.
*/
public File getLocalPath() {
return localPath;
}
/**
* Sets the location of the bundle file on the local filesystem. If the
* file already exists, the bundle will be considered downloaded;
* otherwise the file will be created when download() is called.
*/
public void setLocalPath(File localPath) {
this.localPath = localPath;
}
/**
* Returns the path to the extracted JAR file containing this bundle's
* classes. This file should only exist after the bundle has been
* installed.
*/
public File getJarPath() {
return jarPath;
}
/**
* Sets the path to the extracted JAR file containing this bundle's
* classes. This file will be created as part of installing the bundle.
*/
public void setJarPath(File jarPath) {
this.jarPath = jarPath;
}
/**
* Returns the size of the bundle download in bytes.
*/
public int getSize() {
return Integer.valueOf(DownloadManager.getBundleProperty(getName(),
DownloadManager.SIZE_PROPERTY));
}
/**
* Returns true if the bundle file (getLocalPath()) should be deleted
* when the bundle is successfully installed. Defaults to true.
*/
public boolean getDeleteOnInstall() {
return deleteOnInstall;
}
/**
* Sets whether the bundle file (getLocalPath()) should be deleted
* when the bundle is successfully installed. Defaults to true.
*/
public void setDeleteOnInstall(boolean deleteOnInstall) {
this.deleteOnInstall = deleteOnInstall;
}
/** Sets the current state of this bundle to match reality. */
protected void updateState() {
synchronized(Bundle.class) {
loadReceipts();
if (receipts.contains(name) ||
"true".equals(DownloadManager.getBundleProperty(name,
DownloadManager.INSTALL_PROPERTY)))
state = Bundle.INSTALLED;
else if (localPath.exists())
state = Bundle.DOWNLOADED;
}
}
private String getURL(boolean showUI) throws IOException {
Properties urls = DownloadManager.getBundleURLs(showUI);
String result = urls.getProperty(name + ".zip");
if (result == null) {
result = urls.getProperty(name);
if (result == null) {
DownloadManager.log("Unable to determine bundle URL for " + this);
DownloadManager.log("Bundle URLs: " + urls);
DownloadManager.sendErrorPing(DownloadManager.ERROR_NO_SUCH_BUNDLE);
throw new NullPointerException("Unable to determine URL " +
"for bundle: " + this);
}
}
return result;
}
/**
* Downloads the bundle. This method blocks until the download is
* complete.
*
*@param showProgress true to display a progress dialog
*/
private void download(boolean showProgress) {
if (DownloadManager.isJREComplete())
return;
Mutex mutex = Mutex.create(DownloadManager.MUTEX_PREFIX + name +
".download");
mutex.acquire();
try {
long start = System.currentTimeMillis();
boolean retry;
do {
retry = false;
updateState();
if (state == DOWNLOADED || state == INSTALLED) {
return;
}
File tmp = null;
try {
tmp = new File(localPath + ".tmp");
// tmp.deleteOnExit();
if (DownloadManager.getBaseDownloadURL().equals(
DownloadManager.RESOURCE_URL)) {
// RESOURCE_URL is used during build process, to
// avoid actual network traffic. This is called in
// the SplitJRE DownloadTest to determine which
// classes are needed to support downloads, but we
// bypass the actual HTTP download to simplify the
// build process (it's all native code, so from
// DownloadTest's standpoint it doesn't matter if we
// really call it or not).
String path = "/" + name + ".zip";
InputStream in =
getClass().getResourceAsStream(path);
if (in == null)
throw new IOException("could not locate " +
"resource: " + path);
FileOutputStream out = new FileOutputStream(tmp);
DownloadManager.send(in, out);
in.close();
out.close();
}
else {
try {
String bundleURL = getURL(showProgress);
DownloadManager.log("Downloading from: " +
bundleURL);
DownloadManager.downloadFromURL(bundleURL, tmp,
name.replace('_', '.'), showProgress);
}
catch (HttpRetryException e) {
// Akamai returned a 403, get new URL
DownloadManager.flushBundleURLs();
String bundleURL = getURL(showProgress);
DownloadManager.log("Retrying at new " +
"URL: " + bundleURL);
DownloadManager.downloadFromURL(bundleURL, tmp,
name.replace('_', '.'),
showProgress);
// we intentionally don't do a 403 retry
// again, to avoid infinite retries
}
}
if (!tmp.exists() || tmp.length() == 0) {
if (showProgress) {
// since showProgress = true, native code should
// have offered to retry. Since we ended up here,
// we conclude that download failed & user opted to
// cancel. Set complete to true to stop bugging
// him in the future (if one bundle fails, the
// rest are virtually certain to).
DownloadManager.complete = true;
}
DownloadManager.fatalError(DownloadManager.ERROR_UNSPECIFIED);
}
/**
* Bundle security
*
* Check for corruption/spoofing
*/
/* Create a bundle check from the tmp file */
BundleCheck gottenCheck = BundleCheck.getInstance(tmp);
/* Get the check expected for the Bundle */
BundleCheck expectedCheck = BundleCheck.getInstance(name);
// Do they match?
if (expectedCheck.equals(gottenCheck)) {
// Security check OK, uncompress the bundle file
// into the local path
long uncompressedLength = tmp.length();
localPath.delete();
File uncompressedPath = new File(tmp.getPath() +
".jar0");
if (! extraUncompress(tmp.getPath(),
uncompressedPath.getPath())) {
// Extra uncompression not available, fall
// back to alternative if it is enabled.
if (DownloadManager.debug) {
DownloadManager.log("Uncompressing with GZIP");
}
GZIPInputStream in = new GZIPInputStream( new
BufferedInputStream(new FileInputStream(tmp),
DownloadManager.BUFFER_SIZE));
BufferedOutputStream out = new BufferedOutputStream(
new FileOutputStream(uncompressedPath),
DownloadManager.BUFFER_SIZE);
DownloadManager.send(in,out);
in.close();
out.close();
if (! uncompressedPath.renameTo(localPath)) {
throw new IOException("unable to rename " +
uncompressedPath + " to " + localPath);
}
} else {
if (DownloadManager.debug) {
DownloadManager.log("Uncompressing with LZMA");
}
if (! uncompressedPath.renameTo(localPath)) {
throw new IOException("unable to rename " +
uncompressedPath + " to " + localPath);
}
}
state = DOWNLOADED;
bytesDownloaded += uncompressedLength;
long time = (System.currentTimeMillis() -
start);
DownloadManager.log("Downloaded " + name +
" in " + time + "ms. Downloaded " +
bytesDownloaded + " bytes this session.");
// Normal completion
} else {
// Security check not OK: remove the temp file
// and consult the user
tmp.delete();
DownloadManager.log(
"DownloadManager: Security check failed for " +
"bundle " + name);
// only show dialog if we are not in silent mode
if (showProgress) {
retry = DownloadManager.askUserToRetryDownloadOrQuit(
DownloadManager.ERROR_UNSPECIFIED);
}
if (!retry) {
// User wants to give up
throw new RuntimeException(
"Failed bundle security check and user " +
"canceled");
}
}
}
catch (IOException e) {
// Look for "out of space" using File.getUsableSpace()
// here when downloadFromURL starts throwing IOException
// (or preferably a distinct exception for this case).
DownloadManager.log(e);
}
} while (retry);
} finally {
mutex.release();
}
}
/**
* Calls {@link #queueDownload()} on all of this bundle's dependencies.
*/
void queueDependencies(boolean showProgress) {
try {
String dependencies =
DownloadManager.getBundleProperty(name,
DownloadManager.DEPENDENCIES_PROPERTY);
if (dependencies != null) {
StringTokenizer st = new StringTokenizer(dependencies,
" ,");
while (st.hasMoreTokens()) {
Bundle b = getBundle(st.nextToken());
if (b != null && !b.isInstalled()) {
if (DownloadManager.debug) {
DownloadManager.log("Queueing " + b.name +
" as a dependency of " + name + "...");
}
b.install(showProgress, true, false);
}
}
}
} catch (IOException e) {
// shouldn't happen
DownloadManager.log(e);
}
}
static synchronized ExecutorService getThreadPool() {
if (threadPool == null) {
threadPool = Executors.newFixedThreadPool(THREADS,
new ThreadFactory () {
public Thread newThread(Runnable r) {
Thread result = new Thread(r);
result.setDaemon(true);
return result;
}
}
);
}
return threadPool;
}
private void unpackBundle() throws IOException {
File useJarPath = null;
if (DownloadManager.isWindowsVista()) {
useJarPath = lowJarPath;
File jarDir = useJarPath.getParentFile();
if (jarDir != null) {
jarDir.mkdirs();
}
} else {
useJarPath = jarPath;
}
DownloadManager.log("Unpacking " + this + " to " + useJarPath);
InputStream rawStream = new FileInputStream(localPath);
JarInputStream in = new JarInputStream(rawStream) {
public void close() throws IOException {
// prevent any sub-processes here from actually closing the
// input stream; we'll use rawsStream.close() when we're
// done with it
}
};
try {
File jarTmp = null;
JarEntry entry;
while ((entry = in.getNextJarEntry()) != null) {
String entryName = entry.getName();
if (entryName.equals("classes.pack")) {
File packTmp = new File(useJarPath + ".pack");
packTmp.getParentFile().mkdirs();
DownloadManager.log("Writing temporary .pack file " + packTmp);
OutputStream tmpOut = new FileOutputStream(packTmp);
try {
DownloadManager.send(in, tmpOut);
} finally {
tmpOut.close();
}
// we unpack to a temporary file and then, towards the end
// of this method, use a (hopefully atomic) rename to put it
// into its final location; this should avoid the problem of
// partially-completed downloads. Doing the rename last
// allows us to check for the presence of the JAR file to
// see whether the bundle has in fact been downloaded.
jarTmp = new File(useJarPath + ".tmp");
DownloadManager.log("Writing temporary .jar file " + jarTmp);
unpack(packTmp, jarTmp);
packTmp.delete();
} else if (!entryName.startsWith("META-INF")) {
File dest;
if (DownloadManager.isWindowsVista()) {
dest = new File(lowJavaPath,
entryName.replace('/', File.separatorChar));
} else {
dest = new File(DownloadManager.JAVA_HOME,
entryName.replace('/', File.separatorChar));
}
if (entryName.equals(BUNDLE_JAR_ENTRY_NAME))
dest = useJarPath;
File destTmp = new File(dest + ".tmp");
boolean exists = dest.exists();
if (!exists) {
DownloadManager.log(dest + ".mkdirs()");
dest.getParentFile().mkdirs();
}
try {
DownloadManager.log("Using temporary file " + destTmp);
FileOutputStream out =
new FileOutputStream(destTmp);
try {
byte[] buffer = new byte[2048];
int c;
while ((c = in.read(buffer)) > 0)
out.write(buffer, 0, c);
} finally {
out.close();
}
if (exists)
dest.delete();
DownloadManager.log("Renaming from " + destTmp + " to " + dest);
if (!destTmp.renameTo(dest)) {
throw new IOException("unable to rename " +
destTmp + " to " + dest);
}
} catch (IOException e) {
if (!exists)
throw e;
// otherwise the file already existed and the fact
// that we failed to re-write it probably just
// means that it was in use
}
}
}
// rename the temporary jar into its final location
if (jarTmp != null) {
if (useJarPath.exists())
jarTmp.delete();
else if (!jarTmp.renameTo(useJarPath)) {
throw new IOException("unable to rename " + jarTmp +
" to " + useJarPath);
}
}
if (DownloadManager.isWindowsVista()) {
// move bundle to real location
DownloadManager.log("Using broker to move " + name);
if (!DownloadManager.moveDirWithBroker(
DownloadManager.getKernelJREDir() + name)) {
throw new IOException("unable to create " + name);
}
DownloadManager.log("Broker finished " + name);
}
DownloadManager.log("Finished unpacking " + this);
} finally {
rawStream.close();
}
if (deleteOnInstall) {
localPath.delete();
}
}
public static void unpack(File pack, File jar) throws IOException {
Process p = Runtime.getRuntime().exec(DownloadManager.JAVA_HOME + File.separator +
"bin" + File.separator + "unpack200 -Hoff \"" + pack + "\" \"" + jar + "\"");
try {
p.waitFor();
}
catch (InterruptedException e) {
}
}
/**
* Unpacks and installs the bundle. The bundle's classes are not
* immediately added to the boot class path; this happens when the VM
* attempts to load a class and calls getBootClassPathEntryForClass().
*/
public void install() throws IOException {
install(true, false, true);
}
/**
* Unpacks and installs the bundle, optionally hiding the progress
* indicator. The bundle's classes are not immediately added to the
* boot class path; this happens when the VM attempts to load a class
* and calls getBootClassPathEntryForClass().
*
*@param showProgress true to display a progress dialog
*@param downloadOnly true to download but not install
*@param block true to wait until the operation is complete before returning
*/
public synchronized void install(final boolean showProgress,
final boolean downloadOnly, boolean block) throws IOException {
if (DownloadManager.isJREComplete())
return;
if (state == NOT_DOWNLOADED || state == QUEUED) {
// we allow an already-queued bundle to be placed into the queue
// again, to handle the case where the bundle is queued with
// downloadOnly true and then we try to queue it again with
// downloadOnly false -- the second queue entry will actually
// install it.
if (state != QUEUED) {
DownloadManager.addToTotalDownloadSize(getSize());
state = QUEUED;
}
if (getThreadPool().isShutdown()) {
if (state == NOT_DOWNLOADED || state == QUEUED)
doInstall(showProgress, downloadOnly);
}
else {
Future task = getThreadPool().submit(new Runnable() {
public void run() {
try {
if (state == NOT_DOWNLOADED || state == QUEUED ||
(!downloadOnly && state == DOWNLOADED)) {
doInstall(showProgress, downloadOnly);
}
}
catch (IOException e) {
// ignore
}
}
});
queueDependencies(showProgress);
if (block) {
try {
task.get();
}
catch (Exception e) {
throw new Error(e);
}
}
}
}
else if (state == DOWNLOADED && !downloadOnly)
doInstall(showProgress, false);
}
private void doInstall(boolean showProgress, boolean downloadOnly)
throws IOException {
Mutex mutex = Mutex.create(DownloadManager.MUTEX_PREFIX + name +
".install");
DownloadManager.bundleInstallStart();
try {
mutex.acquire();
updateState();
if (state == NOT_DOWNLOADED || state == QUEUED) {
download(showProgress);
}
if (state == DOWNLOADED && downloadOnly) {
return;
}
if (state == INSTALLED) {
return;
}
if (state != DOWNLOADED) {
DownloadManager.fatalError(DownloadManager.ERROR_UNSPECIFIED);
}
DownloadManager.log("Calling unpackBundle for " + this);
unpackBundle();
DownloadManager.log("Writing receipt for " + this);
writeReceipt();
updateState();
DownloadManager.log("Finished installing " + this + ", state=" + state);
} finally {
if (lowJavaPath != null) {
lowJavaPath.delete();
}
mutex.release();
DownloadManager.bundleInstallComplete();
}
}
synchronized void setState(int state) {
this.state = state;
}
/** Returns <code>true</code> if this bundle has been installed. */
public boolean isInstalled() {
synchronized (Bundle.class) {
updateState();
return state == INSTALLED;
}
}
/**
* Adds an entry to the receipts file indicating that this bundle has
* been successfully downloaded.
*/
private void writeReceipt() {
getReceiptsMutex().acquire();
File useReceiptPath = null;
try {
try {
receipts.add(name);
if (DownloadManager.isWindowsVista()) {
// write out receipts to locallow
useReceiptPath = new File(
DownloadManager.getLocalLowTempBundlePath(),
"receipts");
if (receiptPath.exists()) {
// copy original file to locallow location
DownloadManager.copyReceiptFile(receiptPath,
useReceiptPath);
}
// update receipt in locallow path
// only append if original receipt path exists
FileOutputStream out = new FileOutputStream(useReceiptPath,
receiptPath.exists());
out.write((name + System.getProperty("line.separator")).getBytes("utf-8"));
out.close();
// use broker to move back to real path
if (!DownloadManager.moveFileWithBroker(
DownloadManager.getKernelJREDir()
+ "-bundles" + File.separator + "receipts")) {
throw new IOException("failed to write receipts");
}
} else {
useReceiptPath = receiptPath;
FileOutputStream out = new FileOutputStream(useReceiptPath,
true);
out.write((name + System.getProperty("line.separator")).getBytes("utf-8"));
out.close();
}
} catch (IOException e) {
DownloadManager.log(e);
// safe to continue, as the worst that happens is we
// re-download existing bundles
}
}
finally {
getReceiptsMutex().release();
}
}
public String toString() {
return "Bundle[" + name + "]";
}
}
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
*
* The Java Kernel Bundle security check.
*
* This class is responsible for detail of creating, storing, dispensing, and
* updating bundle security checks and security checks for all the files
* extracted from a bundle. Security checks are cryptographic
* hashcodes that make it impractical to counterfeit a file. The security
* check algorithm is defined by peer class StandaloneMessageDigest. The
* cryptographic
* hashcodes are held in instances of this class as byte arrays and externally
* as hexidecimal string values for Bundle name Property keys. The properties
* are a resource in the Java Kernel core JRE rt.jar and accessed after a
* real or simulated bundle download by peer classes DownloadManager and
* Bundle. Build-time deployment class SplitJRE uses this class to create file
* security checks directly and via a special execution of DownloadManager.
* The main method of this class can be used to create a
* new set of security codes and updated properties for a given JRE path
* and set of bundle names (CWD assume to contain bundle files as <name>.zip).
*
* This is a Sun internal class defined by the Sun implementation and
* intended for JRE/JDK release deployment.
*
* @see sun.jkernel.DownloadManager
* @see sun.jkernel.Bundle
* @see sun.jkernel.StandaloneSHA
* @see sun.jkernel.ByteArrayToFromHexDigits
* See also deploy/src/kernel/share/classes/sun/kernel/SplitJRE.java
*/
package sun.jkernel;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
public class BundleCheck {
/* File buffer size */
private static final int DIGEST_STREAM_BUFFER_SIZE = 2048;
/* The bundle filename suffix */
private static final String BUNDLE_SUFFIX = ".zip";
/* Mutable static state. */
/* Properties (Bundle name/check hex String pairs) for a set of Bundles.
Guarded by this class' object. */
private static volatile Properties properties;
/* Mutable instance state. */
/**
* The bytes of the check value. Guarded by the bundle Mutex (in
* sun.jkernel.DownloadManager) or the fact that sun.kernel.SplitJRE
* and/or DownloadManager with "-download all" runs a single thread.
*/
private byte[] checkBytes;
/* Prevent instantiation by default constructor */
private BundleCheck(){}
/**
* Store the bundle check values as properties to the path specified.
* Only invoked by SplitJRE.
*/
public static void storeProperties(String fullPath) {
try {
File f = new File(fullPath);
f.getParentFile().mkdirs();
OutputStream out = new FileOutputStream(f);
properties.store(out, null);
out.close();
} catch (Exception e) {
throw new RuntimeException(
"BundleCheck: storing properties threw: " + e);
}
}
/**
* Fetch the check value properties as a DownloadManager resource.
*/
private static void loadProperties() {
properties = new Properties();
try {
InputStream in = new BufferedInputStream(
DownloadManager.class.getResourceAsStream(
DownloadManager.CHECK_VALUES_FILE));
if (in == null)
throw new RuntimeException("BundleCheck: unable to locate " +
DownloadManager.CHECK_VALUES_FILE + " as resource");
properties.load(in);
in.close();
} catch (Exception e) {
throw new RuntimeException("BundleCheck: loadProperties threw " +
e);
}
}
/* Get the check value Properties object */
private synchronized static Properties getProperties() {
if (properties == null) {
// If this fails it means addProperty has been used inappropriately
loadProperties();
}
return properties;
}
/* Reset the properties with an empty Properties object */
public static void resetProperties() {
properties = null;
}
/* The BundleCheck expressed as a String */
public String toString() {
return ByteArrayToFromHexDigits.bytesToHexString(checkBytes);
}
/* Add the given BundleCheck as a property to bundleCheckvalueProperties */
private void addProperty(String name) {
// When first called by SplitJRE just start with empty object
// rather than allowing a load to happen, as it does at install time.
if (properties == null) {
properties = new Properties();
}
getProperties().put(name, toString());
}
/* private ctor for creating/initializing a BundleCheck */
private BundleCheck(byte[] checkBytes) {
this.checkBytes = checkBytes;
}
/* private ctor for creating a BundleCheck with a given name and known
Property value. */
private BundleCheck(String name) {
String hexString = getProperties().getProperty(name);
if (hexString == null) {
throw new RuntimeException(
"BundleCheck: no check property for bundle: " + name);
}
this.checkBytes = ByteArrayToFromHexDigits.hexStringToBytes(hexString);
}
/* Make a BundleCheck from the contents of the given file or a Bundle
name. Save the new object's value as a property if saveProperty is
true. Behavior is only defined for name or file being null, but not
both, and for saveProperty to be true only when both name and file
are not null.
Any IO or other exception implies an unexpected and fatal internal
error and results in a RuntimeException. */
private static BundleCheck getInstance(String name,
File file, boolean saveProperty) {
if (file == null ) {
return new BundleCheck(name);
} else {
StandaloneMessageDigest checkDigest = null;
try {
FileInputStream checkFileStream = new FileInputStream(file);
checkDigest = StandaloneMessageDigest.getInstance("SHA-1");
// Compute a check code across all of the file bytes.
// NOTE that every time a bundle is created, even from
// the "same bits", it may be different wrt to the security
// code because of slight variations build to build. For
// example, the JVM build normally contains an
// auto-incrementing build number, built archives might have
// timestamps, etc.
int readCount;
byte[] messageStreamBuff =
new byte[DIGEST_STREAM_BUFFER_SIZE];
do {
readCount = checkFileStream.read(messageStreamBuff);
if (readCount > 0) {
checkDigest.update(messageStreamBuff,0,readCount);
}
} while (readCount != -1);
checkFileStream.close();
} catch (Exception e) {
throw new RuntimeException(
"BundleCheck.addProperty() caught: " + e);
}
BundleCheck bc = new BundleCheck(checkDigest.digest());
if (saveProperty) {
bc.addProperty(name);
}
return bc;
}
}
/* Create a BundleCheck from the given file */
public static BundleCheck getInstance(File file) {
return getInstance(null, file, false);
}
/* Create a BundleCheck from the given bundle name */
static BundleCheck getInstance(String name) {
return getInstance(name, null, false);
}
/* Create a BundleCheck from the given bundle name and file and
use it to make and save a security check Property value. */
public static void addProperty(String name, File file) {
getInstance(name, file, true);
}
/* Create a bundlecheck from the given bundle name and file and
add a Property value for it. */
static void add(String name, File file) {
getInstance(name, file, true).addProperty(name);
}
/* Compare two BundkCheck instances for equal check values */
boolean equals(BundleCheck b) {
if ((checkBytes == null) || (b.checkBytes == null)) {
return false;
}
if (checkBytes.length != b.checkBytes.length) {
return false;
}
for (int i = 0; i < checkBytes.length; i++) {
if (checkBytes[i] != b.checkBytes[i]) {
if (DownloadManager.debug) {
System.out.println(
"BundleCheck.equals mismatch between this: " +
toString() + " and param: " + b.toString());
}
return false;
}
}
return true;
}
/* After SplitJRE is used to restructure the JRE into a "core JRE" and
a set of Java Kernel "bundles", if extra compression is available
the bundles are extracted and rearchived with zero compression by
deploy build make steps. The newly compressed bundle names are then
passed to this main with the path of the kernel core JRE to have new
bundle security check values computed and the corresponding properties
updated in rt.jar. If extra compression isn't available then this main is
never used and the default jar/zip bundle compression and security
codes created by SplitJRE are left in place and ready to use. */
public static void main(String[] args) {
if (args.length < 2) {
System.err.println("Usage: java BundleCheck <jre path> " +
"<bundle 1 name> ... <bundle N name>");
return;
}
// Make a security check code for each bundle file
for (int arg = 1; arg < args.length; arg++) {
BundleCheck.addProperty(args[arg],
new File(args[arg] + BUNDLE_SUFFIX));
}
// Store the new check code properties below the current directory
BundleCheck.storeProperties(DownloadManager.CHECK_VALUES_DIR);
// Now swap the new properties file into the core rt.jar
try {
int status = Runtime.getRuntime().exec(
"jar uf " + args[0] + "\\lib\\rt.jar " +
DownloadManager.CHECK_VALUES_DIR).waitFor();
if (status != 0) {
System.err.println(
"BundleCheck: exec of jar uf gave nonzero status");
return;
}
} catch (Exception e) {
System.err.println("BundleCheck: exec of jar uf threw: " + e);
return;
}
} // main
}
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.jkernel;
/**
* TODO: The JRE and deploy build code (SplitJRE) can be made a bit smarter
* then cryto hashcode byte arrays can be used directly, eliminating the need
* for this class altogether. So just leave this alone until it can be removed.
* TODO: Change "Digits" to "String" for uniformity and more intuitive names.
* A lightweight class to provide convert between hex digits and
* <code>byte[]</code>.
*<p>
* TODO: Try to get this built without the -source 1.3 -target -1.3 options,
* which prevent use of java.text.Format, assuming this wouldn't bloat the
* JK rt.jar. Also, there still might be equivalent code hiding in the JDK
* already, but preliminary searches havn't found it.
*/
public final class ByteArrayToFromHexDigits {
private static final char [] chars = new char[]
{'0','1','2','3','4','5','6','7','8','9', 'A','B','C','D','E','F'};
private static final boolean debug = false;
/**
* Converts the <code>byte[] b</code> into a <code>String</code> of
* hex digits representing the integer values of all the bytes.
*
* @param b byte array to be converted
* @return String representing <code>b</code> in hexadecimal
* @throws IllegalArgumentException if <code>b</code> is null or zero length
*/
public static String bytesToHexString(byte[] b) {
if (debug ) {
System.out.print("I: ");
for(int i=0;i<b.length;i++) {
System.out.format("%02X",b[i]);
}
System.out.println();
}
if ((b == null) || (b.length == 0)) {
throw new IllegalArgumentException("argument null or zero length");
}
StringBuffer buff = new StringBuffer(b.length * 2);
for (int i = 0; i < b.length; i++ ) {
buff.insert(i*2,chars[(b[i] >> 4) & 0xf]);
buff.insert(i*2+1,chars[b[i] & 0xf]);
}
if (debug ) {
System.out.println("O: " + buff.toString());
}
return buff.toString();
}
// Convert one hex character to a 4 bit byte value
private static byte hexCharToByte(char c) throws IllegalArgumentException {
if ((c < '0') ||
( ((c < 'A') && (c > 'F')) && ((c < 'a') && (c > 'f'))) ) {
throw new IllegalArgumentException("not a hex digit");
}
if (c > '9') {
if (c > 'F') {
return (byte) ((c - 'a' + 10) & 0xf);
} else {
return (byte) ((c - 'A' + 10) & 0xf);
}
} else {
return (byte) ((c - '0') & 0xf);
}
}
/**
* Converts the <code>String d</code> assumed to contain a sequence
* of hexadecimal digit characters into a <code>byte[]</code>.
*
* @param d String to be converted
* @return byte array representing the hex string
* @throws IllegalArgumentException if <code>d</code> is odd length,
* contains a character outside the ranges of 0-9, a-f, and A-F,
* or is zero length or null
*/
public static byte[] hexStringToBytes(String d) throws IllegalArgumentException {
if (d == null) {
throw new IllegalArgumentException(
"parameter cannot be null");
}
if (d.length() == 0) {
throw new IllegalArgumentException(
"parameter cannot be zero length");
}
if ((d.length() & 1) != 0) {
throw new IllegalArgumentException(
"odd length string");
}
byte[] b = new byte[d.length() / 2];
// TODO Might be code in the JK initial bundle to do this better (i.e.
// method that tests for a hex char?)
for (int i=0;i<d.length();i+=2) {
b[i/2] = (byte) (( (byte) (hexCharToByte(d.charAt(i))) << 4) +
(byte) hexCharToByte(d.charAt(i+1)));
}
return b;
}
}
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.jkernel;
import java.io.FilterOutputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import sun.jkernel.StandaloneMessageDigest;
/*
* This class provides the main functionality of <code>FilterOutputStream</code>,
* and accumulates a check value as bytes are written to
* it. The check value is available by method <code>getCheckValue</code>.
*<p>
* Operations on the public <code>out</code> field of this class should be
* avoided to prevent an invalid check code being generated.
*
* TODO: The javadoc HTML hasn't been generated and eyeballed for yet.
* TODO: There is a javadoc trick to cause the parent class javadoc to be
* automagically used: try to take advantage of this.
* TODO: Add javadoc links instead of <code>API</code> where it would be useful.
* TODO: Go visit the Docs style guide again and get the periods right and
* consistent for all sun.* classes.
* @author Pete Soper
* @see java.lang.FilterOutputStream
* @see getCheckValue
*/
public class DigestOutputStream extends FilterOutputStream {
private static final String DEFAULT_ALGORITHM = "SHA-1";
private final boolean debug = false;
private StandaloneMessageDigest smd = null;
private void initDigest(String algorithm) throws NoSuchAlgorithmException {
smd = StandaloneMessageDigest.getInstance(algorithm);
}
// The underlying stream.
protected volatile OutputStream out;
/**
* Creates a <code>DigestOutputStream</code> with stream <code>s</code>
* to be checked with using <code>algorithm</code>.
* <p>
* If <code>algorithm</code> is not supported then
* <code>NoSuchAlgorithm</code> is thrown.
* <p>
* See {linkplain sun.security.provider.StandaloneMessageDigest} for an
* implementation-specific list of supported algorithms.
*
* @throws NoSuchAlgorithm if <code>algorithm</code> is not supported
* @see sun.security.provider.StandaloneMessageDigest
*/
/**
* Creates an output stream filter built on top of
* underlying output stream <code>out</code> for checking with
* algorithm <code>algorithm</code>.
* <p>
* If <code>algorithm</code> is not supported then
* <code>NoSuchAlgorithm</code> is thrown.
* <p>
* See {linkplain sun.security.provider.StandaloneMessageDigest} for an
* implementation-specific list of supported algorithms.
*
* @param out the underlying output stream to be assigned to
* the field <tt>this.out</tt> for later use, or
* <code>null</code> if this instance is to be
* created without an underlying stream.
* @param algorithm the check algorithm to use.
* @throws NoSuchAlgorithm if <code>algorithm</code> is not supported
* @see sun.security.provider.StandaloneMessageDigest
* @see DigestInputStream(InputStream, String)
*/
public DigestOutputStream(OutputStream out, String algorithm) throws NoSuchAlgorithmException {
super(out);
initDigest(algorithm);
this.out = out;
}
/**
* Creates an output stream filter built on top of
* underlying output stream <code>out</code> for the default checking
* algorithm.
* <p>
* This implemention provides "SHA-1" as the default checking algorithm.
*
* @param out the underlying output stream to be assigned to
* the field <tt>this.out</tt> for later use, or
* <code>null</code> if this instance is to be
* created without an underlying stream.
* @see DigestInputStream(InputStream)
*/
public DigestOutputStream(OutputStream out) {
super(out);
try {
initDigest(DEFAULT_ALGORITHM);
} catch (NoSuchAlgorithmException e) {
// Impossible to get here, but stranger things have happened...
throw new RuntimeException("DigestOutputStream() unknown algorithm");
}
// superstition from a test failure this.out = out;
}
/**
* Writes a byte specified by <code>v</code> to this stream
* and updates the check information.
*
*
* @param v the byte to be written.
* @throws IOException if an I/O error occurs.
*/
public void write(int v) throws IOException {
super.write(v);
// TODO Could create this array once
byte[] b = new byte[] {(byte) (v & 0xff)};
smd.update(b,0,1);
}
/**
* Writes the bytes in array <code>data</code>
* to this stream and updates the check information.
*
* @param data the data.
* @throws IOException if an I/O error occurs.
* @throws NullPointerException if <code>data</code> is <code>null</code>
*/
public void write(byte[] data) throws IOException {
write(data,0,data.length);
}
/**
* Writes a sub array as a sequence of bytes to this output stream and
* updates the check information.
* @param data the data to be written
* @param ofs the start offset in the data
* @param len the number of bytes that are written
* @throws IOException If an I/O error has occurred.
* @throws NullPointerException if <code>data</code> is <code>null</code>
* @throws IndexOutOfBoundsException If <code>ofs</code> is negative,
* <code>len</code> is negative, or <code>len</code> is greater than
* <code>b.length - ofs</code>
*/
public void write(byte[] data, int ofs, int len) throws IOException {
if (debug) {
System.out.print("DigestOutputStream.write: ");
for (int i=ofs; i<(len - ofs); i++) {
System.out.format("%02X",data[i]);
}
System.out.println();
}
if (data == null) {
throw new NullPointerException("null array in DigestOutputStream.write");
} else if (ofs < 0 || len < 0 || len > data.length - ofs) {
throw new IndexOutOfBoundsException();
}
//super.write(data,ofs,len);
// WATCH OUT: FilterOutputStream does a byte at a time write(byte)
// TODO: Will this work all the time, or is there another caveat
// to publish
out.write(data,ofs,len);
if (debug) {
System.out.println("DigestOutputStream.write before");
}
smd.update(data,ofs,len);
if (debug) {
System.out.println("DigestOutputStream.write after");
}
}
/**
* Closes this file output stream and releases any system resources
* associated with this stream and makes the check value for the stream
* available via <code>getCheckValue</code>. This file output stream may
* no longer be used for writing bytes.
*
* @throws IOException if an I/O error occurs.
* @see getCheckValue
*/
public void close() throws IOException {
super.close();
}
/**
* Return the check value computed for the stream and reset the state of
* check value generation.
*
* @return the check value bytes
*/
public byte[] getCheckValue() {
byte[] b = smd.digest();
if (debug) {
System.out.print("DigestOutputStream.getCheckValue: ");
for (int i=0; i<b.length; i++) {
System.out.format("%02X",b[i]);
}
System.out.println();
}
smd.reset();
return b;
}
/**
* Flushes this output stream.
*
* @throws IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#flush()
*/
public void flush() throws IOException {
super.flush();
}
/**
* Compares two digests for equality. Does a simple byte compare.
*
* @param digesta one of the digests to compare.
*
* @param digestb the other digest to compare.
*
* @return true if the digests are equal, false otherwise.
*/
// public static boolean isEqual(byte digesta[], byte digestb[]) {
// return StandaloneMessageDigest.isEqual(digesta, digestb);
// }
}
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.jkernel;
import java.io.*;
import java.security.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.jar.*;
import java.util.zip.*;
import sun.misc.Launcher;
/**
* Handles the downloading of additional JRE components. The bootstrap class
* loader automatically invokes DownloadManager when it comes across a resource
* that can't be located.
*
*@author Ethan Nicholas
*/
public class DownloadManager {
public static final String KERNEL_DOWNLOAD_URL_PROPERTY =
"kernel.download.url";
public static final String KERNEL_DOWNLOAD_ENABLED_PROPERTY =
"kernel.download.enabled";
public static final String KERNEL_DOWNLOAD_DIALOG_PROPERTY =
"kernel.download.dialog";
public static final String KERNEL_DEBUG_PROPERTY = "kernel.debug";
// disables JRE completion when set to true, used as part of the build
// process
public static final String KERNEL_NOMERGE_PROPERTY = "kernel.nomerge";
public static final String KERNEL_SIMULTANEOUS_DOWNLOADS_PROPERTY =
"kernel.simultaneous.downloads";
// used to bypass some problems with JAR entry modtimes not matching.
// originally was set to zero, but apparently the epochs are different
// for zip and pack so the pack/unpack cycle was causing the modtimes
// to change. With some recent changes to the reconstruction, I'm
// not sure if this is actually necessary anymore.
public static final int KERNEL_STATIC_MODTIME = 10000000;
// indicates that bundles should be grabbed using getResource(), rather
// than downloaded from a network path -- this is used during the build
// process
public static final String RESOURCE_URL = "internal-resource/";
public static final String REQUESTED_BUNDLES_PATH = "lib" + File.separator +
"bundles" + File.separator + "requested.list";
private static final boolean disableDownloadDialog = "false".equals(
System.getProperty(KERNEL_DOWNLOAD_DIALOG_PROPERTY));
static boolean debug = "true".equals(
System.getProperty(KERNEL_DEBUG_PROPERTY));
// points to stderr in case we need to println before System.err is
// initialized
private static OutputStream errorStream;
private static OutputStream logStream;
static String MUTEX_PREFIX;
static boolean complete;
// 1 if jbroker started; 0 otherwise
private static int _isJBrokerStarted = -1;
// maps bundle names to URL strings
private static Properties bundleURLs;
public static final String JAVA_HOME = System.getProperty("java.home");
public static final String USER_HOME = System.getProperty("user.home");
public static final String JAVA_VERSION =
System.getProperty("java.version");
static final int BUFFER_SIZE = 2048;
static volatile boolean jkernelLibLoaded = false;
public static String DEFAULT_DOWNLOAD_URL =
"http://javadl.sun.com/webapps/download/GetList/"
+ System.getProperty("java.runtime.version") + "-kernel/windows-i586/";
private static final String CUSTOM_PREFIX = "custom";
private static final String KERNEL_PATH_SUFFIX = "-kernel";
public static final String JAR_PATH_PROPERTY = "jarpath";
public static final String SIZE_PROPERTY = "size";
public static final String DEPENDENCIES_PROPERTY = "dependencies";
public static final String INSTALL_PROPERTY = "install";
private static boolean reportErrors = true;
static final int ERROR_UNSPECIFIED = 0;
static final int ERROR_DISK_FULL = 1;
static final int ERROR_MALFORMED_BUNDLE_PROPERTIES = 2;
static final int ERROR_DOWNLOADING_BUNDLE_PROPERTIES = 3;
static final int ERROR_MALFORMED_URL = 4;
static final int ERROR_RETRY_CANCELLED = 5;
static final int ERROR_NO_SUCH_BUNDLE = 6;
// tracks whether the current thread is downloading. A count of zero means
// not currently downloading, >0 means the current thread is downloading or
// installing a bundle.
static ThreadLocal<Integer> downloading = new ThreadLocal<Integer>() {
protected Integer initialValue() {
return 0;
}
};
private static File[] additionalBootStrapPaths = { };
private static String[] bundleNames;
private static String[] criticalBundleNames;
private static String downloadURL;
private static boolean visitorIdDetermined;
private static String visitorId;
/**
* File and path where the Check value properties are gotten from
*/
public static String CHECK_VALUES_FILE = "check_value.properties";
static String CHECK_VALUES_DIR = "sun/jkernel/";
static String CHECK_VALUES_PATH = CHECK_VALUES_DIR + CHECK_VALUES_FILE;
/**
* The contents of the bundle.properties file, which contains various
* information about individual bundles.
*/
private static Map<String, Map<String, String>> bundleProperties;
/**
* The contents of the resource_map file, which maps resources
* to their respective bundles.
*/
private static Map<String, String> resourceMap;
/**
* The contents of the file_map file, which maps files
* to their respective bundles.
*/
private static Map<String, String> fileMap;
private static boolean extDirDetermined;
private static boolean extDirIncluded;
static {
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
if (debug)
println("DownloadManager startup");
// this mutex is global and will apply to all different
// version of java kernel installed on the local machine
MUTEX_PREFIX = "jkernel";
boolean downloadEnabled = !"false".equals(
System.getProperty(KERNEL_DOWNLOAD_ENABLED_PROPERTY));
complete = !getBundlePath().exists() ||
!downloadEnabled;
// only load jkernel.dll if we are not "complete".
// DownloadManager will be loaded during build time, before
// jkernel.dll is built. We only need to load jkernel.dll
// when DownloadManager needs to download something, which is
// not necessary during build time
if (!complete) {
loadJKernelLibrary();
log("Log opened");
if (isWindowsVista()) {
getLocalLowTempBundlePath().mkdirs();
}
new Thread() {
public void run() {
startBackgroundDownloads();
}
}.start();
try {
String dummyPath;
if (isWindowsVista()) {
dummyPath = USER_HOME +
"\\appdata\\locallow\\dummy.kernel";
} else {
dummyPath = USER_HOME + "\\dummy.kernel";
}
File f = new File(dummyPath);
FileOutputStream out = new FileOutputStream(f, true);
out.close();
f.deleteOnExit();
} catch (IOException e) {
log(e);
}
// end of warm up code
new Thread("BundleDownloader") {
public void run() {
downloadRequestedBundles();
}
}.start();
}
return null;
}
});
}
static synchronized void loadJKernelLibrary() {
if (!jkernelLibLoaded) {
try {
System.loadLibrary("jkernel");
jkernelLibLoaded = true;
debug = getDebugProperty();
} catch (Exception e) {
throw new Error(e);
}
}
}
static String appendTransactionId(String url) {
StringBuilder result = new StringBuilder(url);
String visitorId = DownloadManager.getVisitorId();
if (visitorId != null) {
if (url.indexOf("?") == -1)
result.append('?');
else
result.append('&');
result.append("transactionId=");
result.append(DownloadManager.getVisitorId());
}
return result.toString();
}
/**
* Returns the URL for the directory from which bundles should be
* downloaded.
*/
static synchronized String getBaseDownloadURL() {
if (downloadURL == null) {
log("Determining download URL...");
loadJKernelLibrary();
/*
* First check if system property has been set - system
* property should take over registry key setting.
*/
downloadURL = System.getProperty(
DownloadManager.KERNEL_DOWNLOAD_URL_PROPERTY);
log("System property kernel.download.url = " + downloadURL);
/*
* Now check if registry key has been set
*/
if (downloadURL == null){
downloadURL = getUrlFromRegistry();
log("getUrlFromRegistry = " + downloadURL);
}
/*
* Use default download url
*/
if (downloadURL == null)
downloadURL = DEFAULT_DOWNLOAD_URL;
log("Final download URL: " + downloadURL);
}
return downloadURL;
}
/**
* Loads a file representing a node tree. The format is described in
* SplitJRE.writeTreeMap(). The node paths (such as
* core/java/lang/Object.class) are interpreted with the root node as the
* value and the remaining nodes as
* the key, so the mapping for this entry would be java/lang/Object.class =
* core.
*/
static Map<String, String> readTreeMap(InputStream rawIn)
throws IOException {
// "token level" refers to the 0-31 byte that occurs prior to every
// token in the stream, and would be e.g. <0> core <1> java <2> lang
// <3> Object.class <3> String.class, which gives us two mappings:
// java/lang/Object.class = core, and java/lang/String.class = core.
// See the format description in SplitJRE.writeTreeMap for more details.
Map<String, String> result = new HashMap<String, String>();
InputStream in = new BufferedInputStream(rawIn);
// holds the current token sequence,
// e.g. {"core", "java", "lang", "Object.class"}
List<String> tokens = new ArrayList<String>();
StringBuilder currentToken = new StringBuilder();
for (;;) {
int c = in.read();
if (c == -1) // eof
break;
if (c < 32) { // new token level
if (tokens.size() > 0) {
// replace the null at the end of the list with the token
// we just finished reading
tokens.set(tokens.size() - 1, currentToken.toString());
}
currentToken.setLength(0);
if (c > tokens.size()) {
// can't increase by more than one token level at a step
throw new InternalError("current token level is " +
(tokens.size() - 1) + " but encountered token " +
"level " + c);
}
else if (c == tokens.size()) {
// token level increased by 1; this means we are still
// adding tokens for the current mapping -- e.g. we have
// read "core", "java", "lang" and are just about to read
// "Object.class"
// add a placeholder for the new token
tokens.add(null);
}
else {
// we just stayed at the same level or backed up one or more
// token levels; this means that the current sequence is
// complete and needs to be added to the result map
StringBuilder key = new StringBuilder();
// combine all tokens except the first into a single string
for (int i = 1; i < tokens.size(); i++) {
if (i > 1)
key.append('/');
key.append(tokens.get(i));
}
// map the combined string to the first token, e.g.
// java/lang/Object.class = core
result.put(key.toString(), tokens.get(0));
// strip off tokens until we get back to the current token
// level
while (c < tokens.size())
tokens.remove(c);
// placeholder for upcoming token
tokens.add(null);
}
}
else if (c < 254) // character
currentToken.append((char) c);
else if (c == 255)
currentToken.append(".class");
else { // out-of-band value
throw new InternalError("internal error processing " +
"resource_map (can't-happen error)");
}
}
if (tokens.size() > 0) // add token we just finished reading
tokens.set(tokens.size() - 1, currentToken.toString());
StringBuilder key = new StringBuilder();
// add the last entry to the map
for (int i = 1; i < tokens.size(); i++) {
if (i > 1)
key.append('/');
key.append(tokens.get(i));
}
if (!tokens.isEmpty())
result.put(key.toString(), tokens.get(0));
in.close();
return Collections.unmodifiableMap(result);
}
/**
* Returns the contents of the resource_map file, which maps
* resources names to their respective bundles.
*/
public static Map<String, String> getResourceMap() throws IOException {
if (resourceMap == null) {
InputStream in = DownloadManager.class.getResourceAsStream("resource_map");
if (in != null) {
in = new BufferedInputStream(in);
try {
resourceMap = readTreeMap(in);
in.close();
}
catch (IOException e) {
// turns out we can be returned a broken stream instead of
// just null
resourceMap = new HashMap<String, String>();
complete = true;
log("Can't find resource_map, forcing complete to true");
}
in.close();
}
else {
resourceMap = new HashMap<String, String>();
complete = true;
log("Can't find resource_map, forcing complete to true");
}
for (int i = 1; ; i++) { // run through the numbered custom bundles
String name = CUSTOM_PREFIX + i;
File customPath = new File(getBundlePath(), name + ".jar");
if (customPath.exists()) {
JarFile custom = new JarFile(customPath);
Enumeration entries = custom.entries();
while (entries.hasMoreElements()) {
JarEntry entry = (JarEntry) entries.nextElement();
if (!entry.isDirectory())
resourceMap.put(entry.getName(), name);
}
}
else
break;
}
}
return resourceMap;
}
/**
* Returns the contents of the file_map file, which maps
* file names to their respective bundles.
*/
public static Map<String, String> getFileMap() throws IOException {
if (fileMap == null) {
InputStream in = DownloadManager.class.getResourceAsStream("file_map");
if (in != null) {
in = new BufferedInputStream(in);
try {
fileMap = readTreeMap(in);
in.close();
}
catch (IOException e) {
// turns out we can be returned a broken stream instead of
// just null
fileMap = new HashMap<String, String>();
complete = true;
log("Can't find file_map, forcing complete to true");
}
in.close();
}
else {
fileMap = new HashMap<String, String>();
complete = true;
log("Can't find file_map, forcing complete to true");
}
}
return fileMap;
}
/**
* Returns the contents of the bundle.properties file, which maps
* bundle names to a pipe-separated list of their properties. Properties
* include:
* jarpath - By default, the JAR files (unpacked from classes.pack in the
* bundle) are stored under lib/bundles. The jarpath property
* overrides this default setting, causing the JAR to be unpacked
* at the specified location. This is used to preserve the
* identity of JRE JAR files such as lib/deploy.jar.
* size - The size of the download in bytes.
*/
private static synchronized Map<String, Map<String, String>> getBundleProperties()
throws IOException {
if (bundleProperties == null) {
InputStream in = DownloadManager.class.getResourceAsStream("bundle.properties");
if (in == null) {
complete = true;
log("Can't find bundle.properties, forcing complete to true");
return null;
}
in = new BufferedInputStream(in);
Properties tmp = new Properties();
tmp.load(in);
bundleProperties = new HashMap<String, Map<String, String>>();
for (Map.Entry e : tmp.entrySet()) {
String key = (String) e.getKey();
String[] properties = ((String) e.getValue()).split("\\|");
Map<String, String> map = new HashMap<String, String>();
for (String entry : properties) {
int equals = entry.indexOf("=");
if (equals == -1)
throw new InternalError("error parsing bundle.properties: " +
entry);
map.put(entry.substring(0, equals).trim(),
entry.substring(equals + 1).trim());
}
bundleProperties.put(key, map);
}
in.close();
}
return bundleProperties;
}
/**
* Returns a single bundle property value loaded from the bundle.properties
* file.
*/
static String getBundleProperty(String bundleName, String property) {
try {
Map<String, Map<String, String>> props = getBundleProperties();
Map/*<String, String>*/ map = props != null ? props.get(bundleName) : null;
return map != null ? (String) map.get(property) : null;
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
/** Returns an array of all supported bundle names. */
static String[] getBundleNames() throws IOException {
if (bundleNames == null) {
Set<String> result = new HashSet<String>();
Map<String, String> resourceMap = getResourceMap();
if (resourceMap != null)
result.addAll(resourceMap.values());
Map<String, String> fileMap = getFileMap();
if (fileMap != null)
result.addAll(fileMap.values());
bundleNames = result.toArray(new String[result.size()]);
}
return bundleNames;
}
/**
* Returns an array of all "critical" (must be downloaded prior to
* completion) bundle names.
*/
private static String[] getCriticalBundleNames() throws IOException {
if (criticalBundleNames == null) {
Set<String> result = new HashSet<String>();
Map<String, String> fileMap = getFileMap();
if (fileMap != null)
result.addAll(fileMap.values());
criticalBundleNames = result.toArray(new String[result.size()]);
}
return criticalBundleNames;
}
public static void send(InputStream in, OutputStream out)
throws IOException {
byte[] buffer = new byte[BUFFER_SIZE];
int c;
while ((c = in.read(buffer)) > 0)
out.write(buffer, 0, c);
}
/**
* Determine whether all bundles have been downloaded, and if so create
* the merged jars that will eventually replace rt.jar and resoures.jar.
* IMPORTANT: this method should only be called from the background
* download process.
*/
static void performCompletionIfNeeded() {
if (debug)
log("DownloadManager.performCompletionIfNeeded: checking (" +
complete + ", " + System.getProperty(KERNEL_NOMERGE_PROPERTY)
+ ")");
if (complete ||
"true".equals(System.getProperty(KERNEL_NOMERGE_PROPERTY)))
return;
Bundle.loadReceipts();
try {
if (debug) {
List critical = new ArrayList(Arrays.asList(getCriticalBundleNames()));
critical.removeAll(Bundle.receipts);
log("DownloadManager.performCompletionIfNeeded: still need " +
critical.size() + " bundles (" + critical + ")");
}
if (Bundle.receipts.containsAll(Arrays.asList(getCriticalBundleNames()))) {
log("DownloadManager.performCompletionIfNeeded: running");
// all done!
new Thread("JarMerger") {
public void run() {
createMergedJars();
}
}.start();
}
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* Returns the bundle corresponding to a given resource path (e.g.
* "java/lang/Object.class"). If the resource does not appear in a bundle,
* null is returned.
*/
public static Bundle getBundleForResource(String resource)
throws IOException {
String bundleName = getResourceMap().get(resource);
return bundleName != null ? Bundle.getBundle(bundleName) : null;
}
/**
* Returns the bundle corresponding to a given JRE file path (e.g.
* "bin/awt.dll"). If the file does not appear in a bundle, null is
* returned.
*/
private static Bundle getBundleForFile(String file) throws IOException {
String bundleName = getFileMap().get(file);
return bundleName != null ? Bundle.getBundle(bundleName) : null;
}
/**
* Returns the path to the lib/bundles directory.
*/
static File getBundlePath() {
return new File(JAVA_HOME, "lib" + File.separatorChar + "bundles");
}
private static String getAppDataLocalLow() {
return USER_HOME + "\\appdata\\locallow\\";
}
public static String getKernelJREDir() {
return "kerneljre" + JAVA_VERSION;
}
static File getLocalLowTempBundlePath() {
return new File(getLocalLowKernelJava() + "-bundles");
}
static String getLocalLowKernelJava() {
return getAppDataLocalLow() + getKernelJREDir();
}
/**
* Returns an array of JAR files which have been added to the boot strap
* class path since the JVM was first booted.
*/
public static synchronized File[] getAdditionalBootStrapPaths() {
return additionalBootStrapPaths != null ? additionalBootStrapPaths :
new File[0];
}
private static void addEntryToBootClassPath(File path) {
// Must acquire these locks in this order
synchronized(Launcher.class) {
synchronized(DownloadManager.class) {
File[] newBootStrapPaths = new File[
additionalBootStrapPaths.length + 1];
System.arraycopy(additionalBootStrapPaths, 0, newBootStrapPaths,
0, additionalBootStrapPaths.length);
newBootStrapPaths[newBootStrapPaths.length - 1] = path;
additionalBootStrapPaths = newBootStrapPaths;
Launcher.flushBootstrapClassPath();
}
}
}
/**
* Scan through java.ext.dirs to see if the lib/ext directory is included.
* If not, we shouldn't be "finding" lib/ext jars for download.
*/
private static synchronized boolean extDirIsIncluded() {
if (!extDirDetermined) {
extDirDetermined = true;
String raw = System.getProperty("java.ext.dirs");
String ext = JAVA_HOME + File.separator + "lib" + File.separator + "ext";
int index = 0;
while (index < raw.length()) {
int newIndex = raw.indexOf(File.pathSeparator, index);
if (newIndex == -1)
newIndex = raw.length();
String path = raw.substring(index, newIndex);
if (path.equals(ext)) {
extDirIncluded = true;
break;
}
index = newIndex + 1;
}
}
return extDirIncluded;
}
private static String doGetBootClassPathEntryForResource(
String resourceName) {
boolean retry = false;
do {
Bundle bundle = null;
try {
bundle = getBundleForResource(resourceName);
if (bundle != null) {
File path = bundle.getJarPath();
boolean isExt = path.getParentFile().getName().equals("ext");
if (isExt && !extDirIsIncluded()) // this is a lib/ext jar, but
return null; // lib/ext isn't in the path
if (getBundleProperty(bundle.getName(), JAR_PATH_PROPERTY) == null) {
// if the bundle doesn't have its own JAR path, that means it's
// going to be merged into rt.jar. If we already have the
// merged rt.jar, we can simply point to that.
Bundle merged = Bundle.getBundle("merged");
if (merged != null && merged.isInstalled()) {
File jar;
if (resourceName.endsWith(".class"))
jar = merged.getJarPath();
else
jar = new File(merged.getJarPath().getPath().replaceAll("merged-rt.jar",
"merged-resources.jar"));
addEntryToBootClassPath(jar);
return jar.getPath();
}
}
if (!bundle.isInstalled()) {
bundle.queueDependencies(true);
log("On-demand downloading " +
bundle.getName() + " for resource " +
resourceName + "...");
bundle.install();
log(bundle + " install finished.");
}
log("Double-checking " + bundle + " state...");
if (!bundle.isInstalled()) {
throw new IllegalStateException("Expected state of " +
bundle + " to be INSTALLED");
}
if (isExt) {
// don't add lib/ext entries to the boot class path, add
// them to the extension classloader instead
Launcher.addURLToExtClassLoader(path.toURL());
return null;
}
if ("javaws".equals(bundle.getName())) {
Launcher.addURLToAppClassLoader(path.toURL());
log("Returning null for javaws");
return null;
}
if ("core".equals(bundle.getName()))
return null;
// else add to boot class path
addEntryToBootClassPath(path);
return path.getPath();
}
return null; // not one of the JRE's classes
}
catch (Throwable e) {
retry = handleException(e);
log("Error downloading bundle for " +
resourceName + ":");
log(e);
if (e instanceof IOException) {
// bundle did not get installed correctly, remove incomplete
// bundle files
if (bundle != null) {
if (bundle.getJarPath() != null) {
File packTmp = new File(bundle.getJarPath() + ".pack");
packTmp.delete();
bundle.getJarPath().delete();
}
if (bundle.getLocalPath() != null) {
bundle.getLocalPath().delete();
}
bundle.setState(Bundle.NOT_DOWNLOADED);
}
}
}
} while (retry);
sendErrorPing(ERROR_RETRY_CANCELLED); // bundle failed to install, user cancelled
return null; // failed, user chose not to retry
}
static synchronized void sendErrorPing(int code) {
try {
File bundlePath;
if (isWindowsVista()) {
bundlePath = getLocalLowTempBundlePath();
} else {
bundlePath = getBundlePath();
}
File tmp = new File(bundlePath, "tmp");
File errors = new File(tmp, "errors");
String errorString = String.valueOf(code);
if (errors.exists()) {
BufferedReader in = new BufferedReader(new FileReader(errors));
String line = in.readLine();
while (line != null) {
if (line.equals(errorString))
return; // we have already pinged this error
line = in.readLine();
}
}
tmp.mkdirs();
Writer out = new FileWriter(errors, true);
out.write(errorString + System.getProperty("line.separator"));
out.close();
postDownloadError(code);
}
catch (IOException e) {
e.printStackTrace();
}
}
/**
* Displays an error dialog and prompts the user to retry or cancel.
* Returns true if the user chose to retry, false if he chose to cancel.
*/
static boolean handleException(Throwable e) {
if (e instanceof IOException) {
// I don't know of a better method to determine the root cause of
// the exception, unfortunately...
int code = ERROR_UNSPECIFIED;
if (e.getMessage().indexOf("not enough space") != -1)
code = ERROR_DISK_FULL;
return askUserToRetryDownloadOrQuit(code);
}
else
return false;
}
static synchronized void flushBundleURLs() {
bundleURLs = null;
}
static synchronized Properties getBundleURLs(boolean showUI)
throws IOException {
if (bundleURLs == null) {
log("Entering DownloadManager.getBundleURLs");
String base = getBaseDownloadURL();
String url = appendTransactionId(base);
// use PID instead of createTempFile or other random filename so as
// to avoid dependencies on the random number generator libraries
File bundlePath = null;
// write temp file to locallow directory on vista
if (isWindowsVista()) {
bundlePath = getLocalLowTempBundlePath();
} else {
bundlePath = getBundlePath();
}
File tmp = new File(bundlePath, "urls." + getCurrentProcessId() +
".properties");
try {
log("Downloading from " + url + " to " + tmp);
downloadFromURL(url, tmp, "", showUI);
bundleURLs = new Properties();
if (tmp.exists()) {
addToTotalDownloadSize((int) tmp.length()); // better late than never
InputStream in = new FileInputStream(tmp);
in = new BufferedInputStream(in);
bundleURLs.load(in);
in.close();
if (bundleURLs.isEmpty()) {
fatalError(ERROR_MALFORMED_BUNDLE_PROPERTIES);
}
} else {
fatalError(ERROR_DOWNLOADING_BUNDLE_PROPERTIES);
}
} finally {
// delete the temp file
if (!debug)
tmp.delete();
}
log("Leaving DownloadManager.getBundleURLs");
// else an error occurred and user chose not to retry; leave
// bundleURLs empty so we don't continually try to re-download it
}
return bundleURLs;
}
/**
* Checks to see if the specified resource is part of a bundle, and if so
* downloads it. Returns either a string which should be added to the boot
* class path (the newly-downloaded JAR's location), or null to indicate
* that it isn't one of the JRE's resources or could not be downloaded.
*/
public static String getBootClassPathEntryForResource(
final String resourceName) {
if (debug)
log("Entering getBootClassPathEntryForResource(" + resourceName + ")");
if (isJREComplete() || downloading == null ||
resourceName.startsWith("sun/jkernel")) {
if (debug)
log("Bailing: " + isJREComplete() + ", " + (downloading == null));
return null;
}
incrementDownloadCount();
try {
String result = (String) AccessController.doPrivileged(
new PrivilegedAction() {
public Object run() {
return (String) doGetBootClassPathEntryForResource(
resourceName);
}
}
);
log("getBootClassPathEntryForResource(" + resourceName + ") == " + result);
return result;
}
finally {
decrementDownloadCount();
}
}
/**
* Called by the boot class loader when it encounters a class it can't find.
* This method will check to see if the class is part of a bundle, and if so
* download it. Returns either a string which should be added to the boot
* class path (the newly-downloaded JAR's location), or null to indicate
* that it isn't one of the JRE's classes or could not be downloaded.
*/
public static String getBootClassPathEntryForClass(final String className) {
return getBootClassPathEntryForResource(className.replace('.', '/') +
".class");
}
private static boolean doDownloadFile(String relativePath)
throws IOException {
Bundle bundle = getBundleForFile(relativePath);
if (bundle != null) {
bundle.queueDependencies(true);
log("On-demand downloading " + bundle.getName() +
" for file " + relativePath + "...");
bundle.install();
return true;
}
return false;
}
/**
* Locates the bundle for the specified JRE file (e.g. "bin/awt.dll") and
* installs it. Returns true if the file is indeed part of the JRE and has
* now been installed, false if the file is not part of the JRE, and throws
* an IOException if the file is part of the JRE but could not be
* downloaded.
*/
public static boolean downloadFile(final String relativePath)
throws IOException {
if (isJREComplete() || downloading == null)
return false;
incrementDownloadCount();
try {
Object result =
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
File path = new File(JAVA_HOME,
relativePath.replace('/', File.separatorChar));
if (path.exists())
return true;
try {
return new Boolean(doDownloadFile(relativePath));
}
catch (IOException e) {
return e;
}
}
});
if (result instanceof Boolean)
return ((Boolean) result).booleanValue();
else
throw (IOException) result;
}
finally {
decrementDownloadCount();
}
}
// increments the counter that tracks whether the current thread is involved
// in any download-related activities. A non-zero count indicates that the
// thread is currently downloading or installing a bundle.
static void incrementDownloadCount() {
downloading.set(downloading.get() + 1);
}
// increments the counter that tracks whether the current thread is involved
// in any download-related activities. A non-zero count indicates that the
// thread is currently downloading or installing a bundle.
static void decrementDownloadCount() {
// will generate an exception if incrementDownloadCount() hasn't been
// called first, this is intentional
downloading.set(downloading.get() - 1);
}
/**
* Returns <code>true</code> if the current thread is in the process of
* downloading a bundle. This is called by ClassLoader.loadLibrary(), so
* that when we run into a library required by the download process itself,
* we don't call back into DownloadManager in an attempt to download it
* (which would lead to infinite recursion).
*
* All classes and libraries required to download classes must by
* definition already be present. So if this method returns true, we are
* currently in the middle of performing a download, and the class or
* library load must be happening due to the download itself. We can
* immediately abort such requests -- the class or library should already
* be present. If it isn't, we're not going to be able to download it,
* since we have just established that it is required to perform a
* download, and we might as well just let the NoClassDefFoundError /
* UnsatisfiedLinkError occur.
*/
public static boolean isCurrentThreadDownloading() {
return downloading != null ? downloading.get() > 0 : false;
}
/**
* Returns true if everything is downloaded and the JRE has been
* reconstructed. Also returns true if kernel functionality is disabled
* for any other reason.
*/
public static boolean isJREComplete() {
return complete;
}
// called by BackgroundDownloader
static void doBackgroundDownloads(boolean showProgress) {
if (!complete) {
if (!showProgress && !debug)
reportErrors = false;
try {
// install swing first for ergonomic reasons
Bundle swing = Bundle.getBundle("javax_swing_core");
if (!swing.isInstalled())
swing.install(showProgress, false, false);
// install remaining bundles
for (String name : getCriticalBundleNames()) {
Bundle bundle = Bundle.getBundle(name);
if (!bundle.isInstalled()) {
bundle.install(showProgress, false, true);
}
}
shutdown();
}
catch (IOException e) {
log(e);
}
}
}
// copy receipt file to destination path specified
static void copyReceiptFile(File from, File to) throws IOException {
DataInputStream in = new DataInputStream(
new BufferedInputStream(new FileInputStream(from)));
OutputStream out = new FileOutputStream(to);
String line = in.readLine();
while (line != null) {
out.write((line + '\n').getBytes("utf-8"));
line = in.readLine();
}
in.close();
out.close();
}
private static void downloadRequestedBundles() {
log("Checking for requested bundles...");
try {
File list = new File(JAVA_HOME, REQUESTED_BUNDLES_PATH);
if (list.exists()) {
FileInputStream in = new FileInputStream(list);
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
send(in, buffer);
in.close();
// split string manually to avoid relying on regexes or
// StringTokenizer
String raw = new String(buffer.toByteArray(), "utf-8");
List/*<String>*/ bundles = new ArrayList/*<String>*/();
StringBuilder token = new StringBuilder();
for (int i = 0; i < raw.length(); i++) {
char c = raw.charAt(i);
if (c == ',' || Character.isWhitespace(c)) {
if (token.length() > 0) {
bundles.add(token.toString());
token.setLength(0);
}
}
else
token.append(c);
}
if (token.length() > 0)
bundles.add(token.toString());
log("Requested bundles: " + bundles);
for (int i = 0; i < bundles.size(); i++) {
Bundle bundle = Bundle.getBundle((String) bundles.get(i));
if (bundle != null && !bundle.isInstalled()) {
log("Downloading " + bundle + " due to requested.list");
bundle.install(true, false, false);
}
}
}
}
catch (IOException e) {
log(e);
}
}
static void fatalError(int code) {
fatalError(code, null);
}
/**
* Called to cleanly shut down the VM when a fatal download error has
* occurred. Calls System.exit() if outside of the Java Plug-In, otherwise
* throws an error.
*/
static void fatalError(int code, String arg) {
sendErrorPing(code);
for (int i = 0; i < Bundle.THREADS; i++)
bundleInstallComplete();
if (reportErrors)
displayError(code, arg);
// inPlugIn check isn't 100% reliable but should be close enough.
// headless is for the browser side of things in the out-of-process
// plug-in
boolean inPlugIn = (Boolean.getBoolean("java.awt.headless") ||
System.getProperty("javaplugin.version") != null);
KernelError error = new KernelError("Java Kernel bundle download failed");
if (inPlugIn)
throw error;
else {
log(error);
System.exit(1);
}
}
// start the background download process using the jbroker broker process
// the method will first launch the broker process, if it is not already
// running
// it will then send the command necessary to start the background download
// process to the broker process
private static void startBackgroundDownloadWithBroker() {
if (!BackgroundDownloader.getBackgroundDownloadProperty()) {
// If getBackgroundDownloadProperty() returns false
// we're doing the downloads from this VM; we don't want to
// spawn another one
return;
}
// launch broker process if necessary
if (!launchBrokerProcess()) {
return;
}
String kernelDownloadURLProperty = getBaseDownloadURL();
String kernelDownloadURL;
// only set KERNEL_DOWNLOAD_URL_PROPERTY if we override
// the default download url
if (kernelDownloadURLProperty == null ||
kernelDownloadURLProperty.equals(DEFAULT_DOWNLOAD_URL)) {
kernelDownloadURL = " ";
} else {
kernelDownloadURL = kernelDownloadURLProperty;
}
startBackgroundDownloadWithBrokerImpl(kernelDownloadURLProperty);
}
private static void startBackgroundDownloads() {
if (!complete) {
if (BackgroundDownloader.getBackgroundMutex().acquire(0)) {
// we don't actually need to hold the mutex -- it was just a
// quick check to see if there is any point in even attempting
// to start the background downloader
BackgroundDownloader.getBackgroundMutex().release();
if (isWindowsVista()) {
// use broker process to start background download
// at high integrity
startBackgroundDownloadWithBroker();
} else {
BackgroundDownloader.startBackgroundDownloads();
}
}
}
}
/**
* Increases the total download size displayed in the download progress
* dialog.
*/
static native void addToTotalDownloadSize(int size);
/**
* Displays a progress dialog while downloading from the specified URL.
*
*@param url the URL string from which to download
*@param file the destination path
*@param name the user-visible name of the component we are downloading
*/
static void downloadFromURL(String url, File file, String name,
boolean showProgress) {
// do not show download dialog if kernel.download.dialog is false
downloadFromURLImpl(url, file, name,
disableDownloadDialog ? false : showProgress);
}
private static native void downloadFromURLImpl(String url, File file,
String name, boolean showProgress);
// This is for testing purposes only - allows to specify URL
// to download kernel bundles from through the registry key.
static native String getUrlFromRegistry();
static native String getVisitorId0();
static native void postDownloadComplete();
static native void postDownloadError(int code);
// Returns the visitor ID set by the installer, will be sent to the server
// during bundle downloads for logging purposes.
static synchronized String getVisitorId() {
if (!visitorIdDetermined) {
visitorIdDetermined = true;
visitorId = getVisitorId0();
}
return visitorId;
}
// display an error message using a native dialog
public static native void displayError(int code, String arg);
// prompt user whether to retry download, or quit
// returns true if the user chose to retry
public static native boolean askUserToRetryDownloadOrQuit(int code);
// returns true if we are running Windows Vista; false otherwise
static native boolean isWindowsVista();
private static native void startBackgroundDownloadWithBrokerImpl(
String command);
private static int isJBrokerStarted() {
if (_isJBrokerStarted == -1) {
// initialize state of jbroker
_isJBrokerStarted = isJBrokerRunning() ? 1 : 0;
}
return _isJBrokerStarted;
}
// returns true if broker process (jbroker) is running; false otherwise
private static native boolean isJBrokerRunning();
// returns true if we are running in IE protected mode; false otherwise
private static native boolean isIEProtectedMode();
private static native boolean launchJBroker(String jbrokerPath);
static native void bundleInstallStart();
static native void bundleInstallComplete();
private static native boolean moveFileWithBrokerImpl(String fromPath,
String userHome);
private static native boolean moveDirWithBrokerImpl(String fromPath,
String userHome);
static boolean moveFileWithBroker(String fromPath) {
// launch jbroker if necessary
if (!launchBrokerProcess()) {
return false;
}
return moveFileWithBrokerImpl(fromPath, USER_HOME);
}
static boolean moveDirWithBroker(String fromPath) {
// launch jbroker if necessary
if (!launchBrokerProcess()) {
return false;
}
return moveDirWithBrokerImpl(fromPath, USER_HOME);
}
private static synchronized boolean launchBrokerProcess() {
// launch jbroker if necessary
if (isJBrokerStarted() == 0) {
// launch jbroker if needed
boolean ret = launchJBroker(JAVA_HOME);
// set state of jbroker
_isJBrokerStarted = ret ? 1 : 0;
return ret;
}
return true;
}
private static class StreamMonitor implements Runnable {
private InputStream istream;
public StreamMonitor(InputStream stream) {
istream = new BufferedInputStream(stream);
new Thread(this).start();
}
public void run() {
byte[] buffer = new byte[4096];
try {
int ret = istream.read(buffer);
while (ret != -1) {
ret = istream.read(buffer);
}
} catch (IOException e) {
try {
istream.close();
} catch (IOException e2) {
} // Should allow clean exit when process shuts down
}
}
}
/** Copy a file tree, excluding certain named files. */
private static void copyAll(File src, File dest, Set/*<String>*/ excludes)
throws IOException {
if (!excludes.contains(src.getName())) {
if (src.isDirectory()) {
File[] children = src.listFiles();
if (children != null) {
for (int i = 0; i < children.length; i++)
copyAll(children[i],
new File(dest, children[i].getName()),
excludes);
}
}
else {
dest.getParentFile().mkdirs();
FileInputStream in = new FileInputStream(src);
FileOutputStream out = new FileOutputStream(dest);
send(in, out);
in.close();
out.close();
}
}
}
public static void dumpOutput(final Process p) {
Thread outputReader = new Thread("outputReader") {
public void run() {
try {
InputStream in = p.getInputStream();
DownloadManager.send(in, System.out);
} catch (IOException e) {
log(e);
}
}
};
outputReader.start();
Thread errorReader = new Thread("errorReader") {
public void run() {
try {
InputStream in = p.getErrorStream();
DownloadManager.send(in, System.err);
} catch (IOException e) {
log(e);
}
}
};
errorReader.start();
}
/**
* Creates the merged rt.jar and resources.jar files.
*/
private static void createMergedJars() {
log("DownloadManager.createMergedJars");
File bundlePath;
if (isWindowsVista()) {
bundlePath = getLocalLowTempBundlePath();
} else {
bundlePath = getBundlePath();
}
File tmp = new File(bundlePath, "tmp");
// explicitly check the final location, not the (potentially) local-low
// location -- a local-low finished isn't good enough to call it done
if (new File(getBundlePath(), "tmp" + File.separator + "finished").exists())
return; // already done
log("DownloadManager.createMergedJars: running");
tmp.mkdirs();
boolean retry = false;
do {
try {
Bundle.getBundle("merged").install(false, false, true);
postDownloadComplete();
// done, write an empty "finished" file to flag completion
File finished = new File(tmp, "finished");
new FileOutputStream(finished).close();
if (isWindowsVista()) {
if (!moveFileWithBroker(getKernelJREDir() +
"-bundles\\tmp\\finished")) {
throw new IOException("unable to create 'finished' file");
}
}
log("DownloadManager.createMergedJars: created " + finished);
// next JRE startup will move these files into their final
// locations, as long as no other JREs are running
// clean up the local low bundle directory on vista
if (isWindowsVista()) {
File tmpDir = getLocalLowTempBundlePath();
File[] list = tmpDir.listFiles();
if (list != null) {
for (int i = 0; i < list.length; i++) {
list[i].delete();
}
}
tmpDir.delete();
log("Finished cleanup, " + tmpDir + ".exists(): " + tmpDir.exists());
}
}
catch (IOException e) {
log(e);
}
}
while (retry);
log("DownloadManager.createMergedJars: finished");
}
private static void shutdown() {
try {
ExecutorService e = Bundle.getThreadPool();
e.shutdown();
e.awaitTermination(60 * 60 * 24, TimeUnit.SECONDS);
}
catch (InterruptedException e) {
}
}
// returns the registry key for kernel.debug
static native boolean getDebugKey();
// returns the final value for the kernel debug property
public static boolean getDebugProperty(){
/*
* Check registry key value
*/
boolean debugEnabled = getDebugKey();
/*
* Check system property - it should override the registry
* key value.
*/
if (System.getProperty(KERNEL_DEBUG_PROPERTY) != null) {
debugEnabled = Boolean.valueOf(
System.getProperty(KERNEL_DEBUG_PROPERTY));
}
return debugEnabled;
}
/**
* Outputs to the error stream even when System.err has not yet been
* initialized.
*/
static void println(String msg) {
if (System.err != null)
System.err.println(msg);
else {
try {
if (errorStream == null)
errorStream = new FileOutputStream(FileDescriptor.err);
errorStream.write((msg +
System.getProperty("line.separator")).getBytes("utf-8"));
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
}
static void log(String msg) {
if (debug) {
println(msg);
try {
if (logStream == null) {
loadJKernelLibrary();
File path = isWindowsVista() ? getLocalLowTempBundlePath() :
getBundlePath();
path = new File(path, "kernel." + getCurrentProcessId() + ".log");
logStream = new FileOutputStream(path);
}
logStream.write((msg +
System.getProperty("line.separator")).getBytes("utf-8"));
logStream.flush();
}
catch (IOException e) {
// ignore
}
}
}
static void log(Throwable e) {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
PrintStream p = new PrintStream(buffer);
e.printStackTrace(p);
p.close();
log(buffer.toString(0));
}
/** Dump the contents of a map to System.out. */
private static void printMap(Map/*<String, String>*/ map) {
int size = 0;
Set<Integer> identityHashes = new HashSet<Integer>();
Iterator/*<Map.Entry<String, String>>*/ i = map.entrySet().iterator();
while (i.hasNext()) {
Map.Entry/*<String, String>*/ e = (Map.Entry) i.next();
String key = (String) e.getKey();
String value = (String) e.getValue();
System.out.println(key + ": " + value);
Integer keyHash = Integer.valueOf(System.identityHashCode(key));
if (!identityHashes.contains(keyHash)) {
identityHashes.add(keyHash);
size += key.length();
}
Integer valueHash = Integer.valueOf(System.identityHashCode(value));
if (!identityHashes.contains(valueHash)) {
identityHashes.add(valueHash);
size += value.length();
}
}
System.out.println(size + " bytes");
}
/** Process the "-dumpmaps" command-line argument. */
private static void dumpMaps() throws IOException {
System.out.println("Resources:");
System.out.println("----------");
printMap(getResourceMap());
System.out.println();
System.out.println("Files:");
System.out.println("----------");
printMap(getFileMap());
}
/** Process the "-download" command-line argument. */
private static void processDownload(String bundleName) throws IOException {
if (bundleName.equals("all")) {
debug = true;
doBackgroundDownloads(true);
performCompletionIfNeeded();
}
else {
Bundle bundle = Bundle.getBundle(bundleName);
if (bundle == null) {
println("Unknown bundle: " + bundleName);
System.exit(1);
}
else
bundle.install();
}
}
static native int getCurrentProcessId();
public static void main(String[] arg) throws Exception {
AccessController.checkPermission(new AllPermission());
boolean valid = false;
if (arg.length == 2 && arg[0].equals("-install")) {
valid = true;
Bundle bundle = new Bundle() {
protected void updateState() {
// the bundle path was provided on the command line, so we
// just claim it has already been "downloaded" to the local
// filesystem
state = DOWNLOADED;
}
};
File jarPath;
int index = 0;
do {
index++;
jarPath = new File(getBundlePath(),
CUSTOM_PREFIX + index + ".jar");
}
while (jarPath.exists());
bundle.setName(CUSTOM_PREFIX + index);
bundle.setLocalPath(new File(arg[1]));
bundle.setJarPath(jarPath);
bundle.setDeleteOnInstall(false);
bundle.install();
}
else if (arg.length == 2 && arg[0].equals("-download")) {
valid = true;
processDownload(arg[1]);
}
else if (arg.length == 1 && arg[0].equals("-dumpmaps")) {
valid = true;
dumpMaps();
}
else if (arg.length == 2 && arg[0].equals("-sha1")) {
valid = true;
System.out.println(BundleCheck.getInstance(new File(arg[1])));
}
else if (arg.length == 1 && arg[0].equals("-downloadtest")) {
valid = true;
File file = File.createTempFile("download", ".test");
for (;;) {
file.delete();
downloadFromURL(getBaseDownloadURL(), file, "URLS", true);
System.out.println("Downloaded " + file.length() + " bytes");
}
}
if (!valid) {
System.out.println("usage: DownloadManager -install <path>.zip |");
System.out.println(" DownloadManager -download " +
"<bundle_name> |");
System.out.println(" DownloadManager -dumpmaps");
System.exit(1);
}
}
}
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.jkernel;
/**
* Thrown to indicate that Java Kernel is unable to install a required bundle
* and the JRE is therefore not adhering to specifications.
*/
public class KernelError extends VirtualMachineError {
/**
* Constructs a <code>KernelError</code> with no detail message.
*/
public KernelError() {
super();
}
/**
* Constructs a <code>KernelError</code> with the specified
* detail message.
*
* @param s the detail message.
*/
public KernelError(String s) {
super(s);
}
}
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.jkernel;
/**
* A mutex which works even between different processes. Currently implemented
* only on Win32.
*
*@author Ethan Nicholas
*/
public class Mutex {
static {
try {
System.loadLibrary("jkernel");
}
catch (Exception e) {
throw new Error(e);
}
}
private String uniqueId;
private long handle;
public static Mutex create(String uniqueId) {
return new Mutex(uniqueId);
}
private Mutex(String uniqueId) {
this.uniqueId = uniqueId;
this.handle = createNativeMutex(uniqueId);
}
private static native long createNativeMutex(String uniqueId);
public native void acquire();
public native boolean acquire(int timeout);
public native void release();
public native void destroyNativeMutex();
public void dispose() {
destroyNativeMutex();
handle = 0;
}
public void finalize() {
dispose();
}
public String toString() {
return "Mutex[" + uniqueId + "]";
}
}
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* This is a pure subset of package-private class
* sun.security.provider.ByteArrayAccess. The subset consists of only the simple
* shift and boolean operations needed for the one current client of this
* class (sun.jkernel.StandaloneSHA) and omits optimization code and comments
* not relevant to the subset. No semantic changes have been made.
* A few long lines were broken to conform to JDK coding style.
* Pete Soper, August, 2007.
*/
package sun.jkernel;
/**
* Methods for converting between byte[] and int[]/long[].
*
* @since 1.6
* @version 1.1, 05/26/06
* @author Andreas Sterbenz
*/
final class StandaloneByteArrayAccess {
private StandaloneByteArrayAccess() {
// empty
}
/**
* byte[] to int[] conversion, little endian byte order.
*/
static void b2iLittle(byte[] in, int inOfs, int[] out, int outOfs,
int len) {
len += inOfs;
while (inOfs < len) {
out[outOfs++] = ((in[inOfs ] & 0xff) )
| ((in[inOfs + 1] & 0xff) << 8)
| ((in[inOfs + 2] & 0xff) << 16)
| ((in[inOfs + 3] ) << 24);
inOfs += 4;
}
}
/**
* int[] to byte[] conversion, little endian byte order.
*/
static void i2bLittle(int[] in, int inOfs, byte[] out, int outOfs,
int len) {
len += outOfs;
while (outOfs < len) {
int i = in[inOfs++];
out[outOfs++] = (byte)(i );
out[outOfs++] = (byte)(i >> 8);
out[outOfs++] = (byte)(i >> 16);
out[outOfs++] = (byte)(i >> 24);
}
}
/**
* byte[] to int[] conversion, big endian byte order.
*/
static void b2iBig(byte[] in, int inOfs, int[] out, int outOfs, int len) {
len += inOfs;
while (inOfs < len) {
out[outOfs++] = ((in[inOfs + 3] & 0xff) )
| ((in[inOfs + 2] & 0xff) << 8)
| ((in[inOfs + 1] & 0xff) << 16)
| ((in[inOfs ] ) << 24);
inOfs += 4;
}
}
/**
* int[] to byte[] conversion, big endian byte order.
*/
static void i2bBig(int[] in, int inOfs, byte[] out, int outOfs, int len) {
len += outOfs;
while (outOfs < len) {
int i = in[inOfs++];
out[outOfs++] = (byte)(i >> 24);
out[outOfs++] = (byte)(i >> 16);
out[outOfs++] = (byte)(i >> 8);
out[outOfs++] = (byte)(i );
}
}
// Store one 32-bit value into out[outOfs..outOfs+3] in big endian order.
static void i2bBig4(int val, byte[] out, int outOfs) {
out[outOfs ] = (byte)(val >> 24);
out[outOfs + 1] = (byte)(val >> 16);
out[outOfs + 2] = (byte)(val >> 8);
out[outOfs + 3] = (byte)(val );
}
/**
* byte[] to long[] conversion, big endian byte order.
*/
static void b2lBig(byte[] in, int inOfs, long[] out, int outOfs, int len) {
len += inOfs;
while (inOfs < len) {
int i1 = ((in[inOfs + 3] & 0xff) )
| ((in[inOfs + 2] & 0xff) << 8)
| ((in[inOfs + 1] & 0xff) << 16)
| ((in[inOfs ] ) << 24);
inOfs += 4;
int i2 = ((in[inOfs + 3] & 0xff) )
| ((in[inOfs + 2] & 0xff) << 8)
| ((in[inOfs + 1] & 0xff) << 16)
| ((in[inOfs ] ) << 24);
out[outOfs++] = ((long)i1 << 32) | (i2 & 0xffffffffL);
inOfs += 4;
}
}
/**
* long[] to byte[] conversion
*/
static void l2bBig(long[] in, int inOfs, byte[] out, int outOfs, int len) {
len += outOfs;
while (outOfs < len) {
long i = in[inOfs++];
out[outOfs++] = (byte)(i >> 56);
out[outOfs++] = (byte)(i >> 48);
out[outOfs++] = (byte)(i >> 40);
out[outOfs++] = (byte)(i >> 32);
out[outOfs++] = (byte)(i >> 24);
out[outOfs++] = (byte)(i >> 16);
out[outOfs++] = (byte)(i >> 8);
out[outOfs++] = (byte)(i );
}
}
}
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* This is a combination and adaptation of subsets of
* <code>java.security.MessageDigest</code> and
* <code>sun.security.provider.DigestBase</code> to provide a class offering
* most of the same public methods of <code>MessageDigest</code> while not
* depending on the Java Security Framework.
* <p>
* One algorithm is currently supported: "SHA-1".
* <p>
* NOTE If <code>java.security.MessageDigest</code>,
* <code>sun.security.provider.DigestBase</code> or
* <code>sun.security.provider.SHA</code> are modified, review of those
* modifications should be done to determine any possible implications for this
* class and <code>StandaloneSHA</code>.
*/
package sun.jkernel;
import java.security.DigestException;
import java.security.ProviderException;
import java.security.NoSuchAlgorithmException;
/**
* (Adapted from the <code>sun.security.provider.DigestBase</code> doc).
* This is a simple subset of the Common base message digest implementation
* for the Sun provider.
* It implements most of the JCA methods as suitable for a Java message
* digest
* implementation of an algorithm based on a compression function (as all
* commonly used algorithms are). The individual digest subclasses only need to
* implement the following methods:
*
* . abstract void implCompress(byte[] b, int ofs);
* . abstract void implDigest(byte[] out, int ofs);
* . abstract void implReset();
* <p>
* No support for a clone() method is provided.
* <p>
* See the inline documentation for details.
*
* @since 1.5
* @version 1.3, 08/08/07
* @author Andreas Sterbenz (MessageDigest)
* @author Pete Soper (this derived class)
*/
public abstract class StandaloneMessageDigest {
public static final boolean debug = false;
/*
* (Copied/adapted from <code>java.security.MessageDigest</code>
*
* This is a subset/simplification <code>java.security.MessageDigest</code>
* that supports a fixed set of hashcode mechanisms (currently just
* SHA-1) while preserving the following MessageDigest methods:
*
* public MessageDigest getInstance(String algorithm)
* public final int getDigestLength()
* public void reset()
* public byte[] digest()
* public void update(byte[] input, int offset, int len)
* public final String getAlgorithm()
* <p>
* NOTE that the clone() method is not provided.
*/
/**
* Prevent direct instantiation except via the factory method.
*/
private StandaloneMessageDigest() {
// Keep javac happy.
digestLength = 0;
blockSize = 0;
algorithm = null;
buffer = null;
}
private String algorithm;
// The state of this digest
private static final int INITIAL = 0;
private static final int IN_PROGRESS = 1;
private int state = INITIAL;
/**
* Returns a StandaloneMessageDigest object that implements the specified
* digest algorithm.
*
* <p> This method returns a new StandaloneMessageDigest for a single
* algorithm provider.
*
* @param algorithm the name of the algorithm requested.
*
* @return a standalone Message Digest object that implements the specified algorithm.
*
* @exception NoSuchAlgorithmException if algorithm not supported
*
*/
public static StandaloneMessageDigest getInstance(String algorithm)
throws NoSuchAlgorithmException {
if (! algorithm.equals("SHA-1")) {
throw new NoSuchAlgorithmException(algorithm + " not found");
} else {
return new StandaloneSHA();
}
}
/**
* Updates the digest using the specified array of bytes, starting
* at the specified offset.
*
* @param input the array of bytes.
*
* @param offset the offset to start from in the array of bytes.
*
* @param len the number of bytes to use, starting at
* <code>offset</code>.
*/
public void update(byte[] input, int offset, int len) {
if (debug) {
System.out.println("StandaloneMessageDigest.update");
(new Exception()).printStackTrace();
}
if (input == null) {
throw new IllegalArgumentException("No input buffer given");
}
if (input.length - offset < len) {
throw new IllegalArgumentException("Input buffer too short");
}
// No need to check for negative offset: engineUpdate does this
engineUpdate(input, offset, len);
state = IN_PROGRESS;
}
/**
* Completes the hash computation by performing final operations
* such as padding. The digest is reset after this call is made.
*
* @return the array of bytes for the resulting hash value.
*/
public byte[] digest() {
if (debug) {
System.out.println("StandaloneMessageDigest.digest");
}
/* Resetting is the responsibility of implementors. */
byte[] result = engineDigest();
state = INITIAL;
return result;
}
/**
* Compares two digests for equality. Does a simple byte compare.
*
* @param digesta one of the digests to compare.
*
* @param digestb the other digest to compare.
*
* @return true if the digests are equal, false otherwise.
*/
public static boolean isEqual(byte digesta[], byte digestb[]) {
if (digesta.length != digestb.length)
return false;
for (int i = 0; i < digesta.length; i++) {
if (digesta[i] != digestb[i]) {
return false;
}
}
return true;
}
/**
* Resets the digest for further use.
*/
public void reset() {
if (debug) {
System.out.println("StandaloneMessageDigest.reset");
}
engineReset();
state = INITIAL;
}
/**
* Returns a string that identifies the algorithm, independent of
* implementation details. The name should be a standard
* Java Security name (such as "SHA", "MD5", and so on).
* See Appendix A in the <a href=
* "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
* Java Cryptography Architecture API Specification &amp; Reference </a>
* for information about standard algorithm names.
*
* @return the name of the algorithm
*/
public final String getAlgorithm() {
return this.algorithm;
}
/**
* Returns the length of the digest in bytes.
*
* @return the digest length in bytes.
*
* @since 1.2
*/
public final int getDigestLength() {
return engineGetDigestLength();
}
//* End of copied/adapted <code>java.security.MessageDigest</code>
// Start of copied/adapted <code>sun.security.provider.DigestBase</code>
// one element byte array, temporary storage for update(byte)
private byte[] oneByte;
// length of the message digest in bytes
private final int digestLength;
// size of the input to the compression function in bytes
private final int blockSize;
// buffer to store partial blocks, blockSize bytes large
// Subclasses should not access this array directly except possibly in their
// implDigest() method. See MD5.java as an example.
final byte[] buffer;
// offset into buffer
private int bufOfs;
// number of bytes processed so far. subclasses should not modify
// this value.
// also used as a flag to indicate reset status
// -1: need to call engineReset() before next call to update()
// 0: is already reset
long bytesProcessed;
/**
* Main constructor.
*/
StandaloneMessageDigest(String algorithm, int digestLength, int blockSize) {
// super();
this.algorithm = algorithm;
this.digestLength = digestLength;
this.blockSize = blockSize;
buffer = new byte[blockSize];
}
// return digest length. See JCA doc.
protected final int engineGetDigestLength() {
return digestLength;
}
// single byte update. See JCA doc.
protected final void engineUpdate(byte b) {
if (oneByte == null) {
oneByte = new byte[1];
}
oneByte[0] = b;
engineUpdate(oneByte, 0, 1);
}
// array update. See JCA doc.
protected final void engineUpdate(byte[] b, int ofs, int len) {
if (len == 0) {
return;
}
if ((ofs < 0) || (len < 0) || (ofs > b.length - len)) {
throw new ArrayIndexOutOfBoundsException();
}
if (bytesProcessed < 0) {
engineReset();
}
bytesProcessed += len;
// if buffer is not empty, we need to fill it before proceeding
if (bufOfs != 0) {
int n = Math.min(len, blockSize - bufOfs);
System.arraycopy(b, ofs, buffer, bufOfs, n);
bufOfs += n;
ofs += n;
len -= n;
if (bufOfs >= blockSize) {
// compress completed block now
implCompress(buffer, 0);
bufOfs = 0;
}
}
// compress complete blocks
while (len >= blockSize) {
implCompress(b, ofs);
len -= blockSize;
ofs += blockSize;
}
// copy remainder to buffer
if (len > 0) {
System.arraycopy(b, ofs, buffer, 0, len);
bufOfs = len;
}
}
// reset this object. See JCA doc.
protected final void engineReset() {
if (bytesProcessed == 0) {
// already reset, ignore
return;
}
implReset();
bufOfs = 0;
bytesProcessed = 0;
}
// return the digest. See JCA doc.
protected final byte[] engineDigest() throws ProviderException {
byte[] b = new byte[digestLength];
try {
engineDigest(b, 0, b.length);
} catch (DigestException e) {
throw (ProviderException)
new ProviderException("Internal error").initCause(e);
}
return b;
}
// return the digest in the specified array. See JCA doc.
protected final int engineDigest(byte[] out, int ofs, int len)
throws DigestException {
if (len < digestLength) {
throw new DigestException("Length must be at least "
+ digestLength + " for " + algorithm + "digests");
}
if ((ofs < 0) || (len < 0) || (ofs > out.length - len)) {
throw new DigestException("Buffer too short to store digest");
}
if (bytesProcessed < 0) {
engineReset();
}
implDigest(out, ofs);
bytesProcessed = -1;
return digestLength;
}
/**
* Core compression function. Processes blockSize bytes at a time
* and updates the state of this object.
*/
abstract void implCompress(byte[] b, int ofs);
/**
* Return the digest. Subclasses do not need to reset() themselves,
* StandaloneMessageDigest calls implReset() when necessary.
*/
abstract void implDigest(byte[] out, int ofs);
/**
* Reset subclass specific state to their initial values. StandaloneMessageDigest
* calls this method when necessary.
*/
abstract void implReset();
// padding used for the MD5, and SHA-* message digests
static final byte[] padding;
static {
// we need 128 byte padding for SHA-384/512
// and an additional 8 bytes for the high 8 bytes of the 16
// byte bit counter in SHA-384/512
padding = new byte[136];
padding[0] = (byte)0x80;
}
}
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.jkernel;
import static sun.jkernel.StandaloneByteArrayAccess.*;
/**
* This is a slightly modified subset of the
* <code>sun.security.provider.SHA</code> class that
* is not dependent on the regular Java Security framework classes. It
* implements the Secure Hash Algorithm (SHA-1) developed by
* the National Institute of Standards and Technology along with the
* National Security Agency. This is the updated version of SHA
* fip-180 as superseded by fip-180-1.
* <p>
* The <code>sun.security.provider.SHA.clonde()</code> method is not
* implemented and other, formerly public methods, are package private.
*
*/
final class StandaloneSHA extends StandaloneMessageDigest {
static final boolean debug = false;
// Buffer of int's and count of characters accumulated
// 64 bytes are included in each hash block so the low order
// bits of count are used to know how to pack the bytes into ints
// and to know when to compute the block and start the next one.
private final int[] W;
// state of this
private final int[] state;
/**
* Creates a new StandaloneSHA object.
*/
StandaloneSHA() {
super("SHA-1", 20, 64);
state = new int[5];
W = new int[80];
implReset();
}
/**
* Resets the buffers and hash value to start a new hash.
*/
void implReset() {
if (debug) {
System.out.print("StandaloneSHA.implR: " );
}
state[0] = 0x67452301;
state[1] = 0xefcdab89;
state[2] = 0x98badcfe;
state[3] = 0x10325476;
state[4] = 0xc3d2e1f0;
}
/**
* Computes the final hash and copies the 20 bytes to the output array.
*/
void implDigest(byte[] out, int ofs) {
if (debug) {
System.out.print("StandaloneSHA.implD: " );
}
long bitsProcessed = bytesProcessed << 3;
int index = (int)bytesProcessed & 0x3f;
int padLen = (index < 56) ? (56 - index) : (120 - index);
engineUpdate(padding, 0, padLen);
// System.out.println("Inserting: " + bitsProcessed);
StandaloneByteArrayAccess.i2bBig4((int)(bitsProcessed >>> 32), buffer, 56);
StandaloneByteArrayAccess.i2bBig4((int)bitsProcessed, buffer, 60);
implCompress(buffer, 0);
StandaloneByteArrayAccess.i2bBig(state, 0, out, ofs, 20);
}
// Constants for each round
private final static int round1_kt = 0x5a827999;
private final static int round2_kt = 0x6ed9eba1;
private final static int round3_kt = 0x8f1bbcdc;
private final static int round4_kt = 0xca62c1d6;
/**
* Compute a the hash for the current block.
*
* This is in the same vein as Peter Gutmann's algorithm listed in
* the back of Applied Cryptography, Compact implementation of
* "old" NIST Secure Hash Algorithm.
*/
void implCompress(byte[] buf, int ofs) {
if (debug) {
System.out.print("StandaloneSHA.implC: " );
for (int i=ofs; i<buf.length; i++) {
System.out.format("%02X",buf[i]);
}
System.out.println();
}
StandaloneByteArrayAccess.b2iBig(buf, ofs, W, 0, 64);
// The first 16 ints have the byte stream, compute the rest of
// the buffer
for (int t = 16; t <= 79; t++) {
int temp = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
W[t] = (temp << 1) | (temp >>> 31);
}
int a = state[0];
int b = state[1];
int c = state[2];
int d = state[3];
int e = state[4];
// Round 1
for (int i = 0; i < 20; i++) {
int temp = ((a<<5) | (a>>>(32-5))) +
((b&c)|((~b)&d))+ e + W[i] + round1_kt;
e = d;
d = c;
c = ((b<<30) | (b>>>(32-30)));
b = a;
a = temp;
}
// Round 2
for (int i = 20; i < 40; i++) {
int temp = ((a<<5) | (a>>>(32-5))) +
(b ^ c ^ d) + e + W[i] + round2_kt;
e = d;
d = c;
c = ((b<<30) | (b>>>(32-30)));
b = a;
a = temp;
}
// Round 3
for (int i = 40; i < 60; i++) {
int temp = ((a<<5) | (a>>>(32-5))) +
((b&c)|(b&d)|(c&d)) + e + W[i] + round3_kt;
e = d;
d = c;
c = ((b<<30) | (b>>>(32-30)));
b = a;
a = temp;
}
// Round 4
for (int i = 60; i < 80; i++) {
int temp = ((a<<5) | (a>>>(32-5))) +
(b ^ c ^ d) + e + W[i] + round4_kt;
e = d;
d = c;
c = ((b<<30) | (b>>>(32-30)));
b = a;
a = temp;
}
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
}
}
...@@ -78,4 +78,3 @@ public class OperatingSystemImpl implements OperatingSystemMXBean { ...@@ -78,4 +78,3 @@ public class OperatingSystemImpl implements OperatingSystemMXBean {
} }
} }
...@@ -419,4 +419,3 @@ class ThreadImpl implements ThreadMXBean { ...@@ -419,4 +419,3 @@ class ThreadImpl implements ThreadMXBean {
} }
} }
...@@ -38,6 +38,7 @@ import java.util.StringTokenizer; ...@@ -38,6 +38,7 @@ import java.util.StringTokenizer;
import java.util.Set; import java.util.Set;
import java.util.Vector; import java.util.Vector;
import java.security.AccessController; import java.security.AccessController;
import java.security.AllPermission;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction; import java.security.PrivilegedExceptionAction;
import java.security.AccessControlContext; import java.security.AccessControlContext;
...@@ -49,7 +50,8 @@ import java.security.CodeSource; ...@@ -49,7 +50,8 @@ import java.security.CodeSource;
import sun.security.action.GetPropertyAction; import sun.security.action.GetPropertyAction;
import sun.security.util.SecurityConstants; import sun.security.util.SecurityConstants;
import sun.net.www.ParseUtil; import sun.net.www.ParseUtil;
import sun.jkernel.Bundle;
import sun.jkernel.DownloadManager;
/** /**
* This class is used by the system to launch the main application. * This class is used by the system to launch the main application.
...@@ -116,6 +118,18 @@ public class Launcher { ...@@ -116,6 +118,18 @@ public class Launcher {
return loader; return loader;
} }
public static void addURLToAppClassLoader(URL u) {
AccessController.checkPermission(new AllPermission());
ClassLoader loader = Launcher.getLauncher().getClassLoader();
((Launcher.AppClassLoader) loader).addAppURL(u);
}
public static void addURLToExtClassLoader(URL u) {
AccessController.checkPermission(new AllPermission());
ClassLoader loader = Launcher.getLauncher().getClassLoader();
((Launcher.ExtClassLoader) loader.getParent()).addExtURL(u);
}
/* /*
* The class loader used for loading installed extensions. * The class loader used for loading installed extensions.
*/ */
...@@ -233,6 +247,16 @@ public class Launcher { ...@@ -233,6 +247,16 @@ public class Launcher {
return null; return null;
} }
protected Class findClass(String name) throws ClassNotFoundException {
if (VM.isBootedKernelVM()) {
// Check for download before we look for it. If
// DownloadManager ends up downloading it, it will add it to
// our search path before we proceed to the findClass().
DownloadManager.getBootClassPathEntryForClass(name);
}
return super.findClass(name);
}
private static AccessControlContext getContext(File[] dirs) private static AccessControlContext getContext(File[] dirs)
throws IOException throws IOException
{ {
...@@ -297,6 +321,9 @@ public class Launcher { ...@@ -297,6 +321,9 @@ public class Launcher {
public Class loadClass(String name, boolean resolve) public Class loadClass(String name, boolean resolve)
throws ClassNotFoundException throws ClassNotFoundException
{ {
if (VM.isBootedKernelVM()) {
DownloadManager.getBootClassPathEntryForClass(name);
}
int i = name.lastIndexOf('.'); int i = name.lastIndexOf('.');
if (i != -1) { if (i != -1) {
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
...@@ -353,39 +380,66 @@ public class Launcher { ...@@ -353,39 +380,66 @@ public class Launcher {
return acc; return acc;
} }
void addAppURL(URL url) {
super.addURL(url);
}
} }
public static URLClassPath getBootstrapClassPath() { private static URLClassPath bootstrapClassPath;
String prop = AccessController.doPrivileged(
new GetPropertyAction("sun.boot.class.path")); public static synchronized URLClassPath getBootstrapClassPath() {
URL[] urls; if (bootstrapClassPath == null) {
if (prop != null) { String prop = AccessController.doPrivileged(
final String path = prop; new GetPropertyAction("sun.boot.class.path"));
urls = AccessController.doPrivileged( URL[] urls;
new PrivilegedAction<URL[]>() { if (prop != null) {
public URL[] run() { final String path = prop;
File[] classPath = getClassPath(path); urls = AccessController.doPrivileged(
int len = classPath.length; new PrivilegedAction<URL[]>() {
Set<File> seenDirs = new HashSet<File>(); public URL[] run() {
for (int i = 0; i < len; i++) { File[] classPath = getClassPath(path);
File curEntry = classPath[i]; int len = classPath.length;
// Negative test used to properly handle Set<File> seenDirs = new HashSet<File>();
// nonexistent jars on boot class path for (int i = 0; i < len; i++) {
if (!curEntry.isDirectory()) { File curEntry = classPath[i];
curEntry = curEntry.getParentFile(); // Negative test used to properly handle
} // nonexistent jars on boot class path
if (curEntry != null && seenDirs.add(curEntry)) { if (!curEntry.isDirectory()) {
MetaIndex.registerDirectory(curEntry); curEntry = curEntry.getParentFile();
}
if (curEntry != null && seenDirs.add(curEntry)) {
MetaIndex.registerDirectory(curEntry);
}
} }
return pathToURLs(classPath);
} }
return pathToURLs(classPath);
} }
} );
); } else {
} else { urls = new URL[0];
urls = new URL[0]; }
bootstrapClassPath = new URLClassPath(urls, factory);
if (VM.isBootedKernelVM()) {
final File[] additionalBootStrapPaths =
DownloadManager.getAdditionalBootStrapPaths();
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
for (int i=0; i<additionalBootStrapPaths.length; i++) {
bootstrapClassPath.addURL(
getFileURL(additionalBootStrapPaths[i]));
}
return null;
}
});
}
} }
return new URLClassPath(urls, factory); return bootstrapClassPath;
}
public static synchronized void flushBootstrapClassPath() {
bootstrapClassPath = null;
} }
private static URL[] pathToURLs(File[] path) { private static URL[] pathToURLs(File[] path) {
......
...@@ -81,6 +81,7 @@ public class PerformanceLogger { ...@@ -81,6 +81,7 @@ public class PerformanceLogger {
private static Vector<TimeData> times; private static Vector<TimeData> times;
private static String logFileName = null; private static String logFileName = null;
private static Writer logWriter = null; private static Writer logWriter = null;
private static long baseTime;
static { static {
String perfLoggingProp = String perfLoggingProp =
...@@ -187,6 +188,16 @@ public class PerformanceLogger { ...@@ -187,6 +188,16 @@ public class PerformanceLogger {
} }
} }
/**
* Sets the base time, output can then
* be displayed as offsets from the base time;.
*/
public static void setBaseTime(long time) {
if (loggingEnabled()) {
baseTime = time;
}
}
/** /**
* Sets the start time. * Sets the start time.
* This version of the method is * This version of the method is
...@@ -281,7 +292,8 @@ public class PerformanceLogger { ...@@ -281,7 +292,8 @@ public class PerformanceLogger {
TimeData td = times.get(i); TimeData td = times.get(i);
if (td != null) { if (td != null) {
writer.write(i + " " + td.getMessage() + ": " + writer.write(i + " " + td.getMessage() + ": " +
td.getTime() + "\n"); (td.getTime() - baseTime) + "\n");
} }
} }
} }
......
...@@ -346,6 +346,11 @@ public class VM { ...@@ -346,6 +346,11 @@ public class VM {
private native static void getThreadStateValues(int[][] vmThreadStateValues, private native static void getThreadStateValues(int[][] vmThreadStateValues,
String[][] vmThreadStateNames); String[][] vmThreadStateNames);
private static boolean kernelVM;
public static boolean isBootedKernelVM() {
return booted && kernelVM;
}
static { static {
initialize(); initialize();
} }
......
...@@ -607,14 +607,6 @@ getStringCp1252Chars(JNIEnv *env, jstring jstr) ...@@ -607,14 +607,6 @@ getStringCp1252Chars(JNIEnv *env, jstring jstr)
return result; return result;
} }
enum {
NO_ENCODING_YET = 0, /* "sun.jnu.encoding" not yet set */
NO_FAST_ENCODING, /* Platform encoding is not fast */
FAST_8859_1, /* ISO-8859-1 */
FAST_CP1252, /* MS-DOS Cp1252 */
FAST_646_US /* US-ASCII : ISO646-US */
};
static int fastEncoding = NO_ENCODING_YET; static int fastEncoding = NO_ENCODING_YET;
static jstring jnuEncoding = NULL; static jstring jnuEncoding = NULL;
...@@ -622,10 +614,14 @@ static jstring jnuEncoding = NULL; ...@@ -622,10 +614,14 @@ static jstring jnuEncoding = NULL;
static jmethodID String_init_ID; /* String(byte[], enc) */ static jmethodID String_init_ID; /* String(byte[], enc) */
static jmethodID String_getBytes_ID; /* String.getBytes(enc) */ static jmethodID String_getBytes_ID; /* String.getBytes(enc) */
int getFastEncoding() {
return fastEncoding;
}
/* Initialize the fast encoding. If the "sun.jnu.encoding" property /* Initialize the fast encoding. If the "sun.jnu.encoding" property
* has not yet been set, we leave fastEncoding == NO_ENCODING_YET. * has not yet been set, we leave fastEncoding == NO_ENCODING_YET.
*/ */
static void void
initializeEncoding(JNIEnv *env) initializeEncoding(JNIEnv *env)
{ {
jstring propname = 0; jstring propname = 0;
...@@ -719,44 +715,47 @@ JNIEXPORT jstring JNICALL ...@@ -719,44 +715,47 @@ JNIEXPORT jstring JNICALL
JNU_NewStringPlatform(JNIEnv *env, const char *str) JNU_NewStringPlatform(JNIEnv *env, const char *str)
{ {
jstring result; jstring result;
jbyteArray hab = 0; result = nativeNewStringPlatform(env, str);
int len; if (result == NULL) {
jbyteArray hab = 0;
if (fastEncoding == NO_ENCODING_YET) int len;
initializeEncoding(env);
if (fastEncoding == NO_ENCODING_YET)
if ((fastEncoding == FAST_8859_1) || (fastEncoding == NO_ENCODING_YET)) initializeEncoding(env);
return newString8859_1(env, str);
if (fastEncoding == FAST_646_US) if ((fastEncoding == FAST_8859_1) || (fastEncoding == NO_ENCODING_YET))
return newString646_US(env, str); return newString8859_1(env, str);
if (fastEncoding == FAST_CP1252) if (fastEncoding == FAST_646_US)
return newStringCp1252(env, str); return newString646_US(env, str);
if (fastEncoding == FAST_CP1252)
if ((*env)->EnsureLocalCapacity(env, 2) < 0) return newStringCp1252(env, str);
return 0;
if ((*env)->EnsureLocalCapacity(env, 2) < 0)
len = (int)strlen(str); return NULL;
hab = (*env)->NewByteArray(env, len);
if (hab != 0) { len = (int)strlen(str);
(*env)->SetByteArrayRegion(env, hab, 0, len, (jbyte *)str); hab = (*env)->NewByteArray(env, len);
if (jnuEncodingSupported(env)) { if (hab != 0) {
result = (*env)->NewObject(env, JNU_ClassString(env), (*env)->SetByteArrayRegion(env, hab, 0, len, (jbyte *)str);
String_init_ID, hab, jnuEncoding); if (jnuEncodingSupported(env)) {
} else { result = (*env)->NewObject(env, JNU_ClassString(env),
/*If the encoding specified in sun.jnu.encoding is not endorsed String_init_ID, hab, jnuEncoding);
by "Charset.isSupported" we have to fall back to use String(byte[]) } else {
explicitly here without specifying the encoding name, in which the /*If the encoding specified in sun.jnu.encoding is not endorsed
StringCoding class will pickup the iso-8859-1 as the fallback by "Charset.isSupported" we have to fall back to use String(byte[])
converter for us. explicitly here without specifying the encoding name, in which the
*/ StringCoding class will pickup the iso-8859-1 as the fallback
jmethodID mid = (*env)->GetMethodID(env, JNU_ClassString(env), converter for us.
"<init>", "([B)V"); */
result = (*env)->NewObject(env, JNU_ClassString(env), mid, hab); jmethodID mid = (*env)->GetMethodID(env, JNU_ClassString(env),
"<init>", "([B)V");
result = (*env)->NewObject(env, JNU_ClassString(env), mid, hab);
}
(*env)->DeleteLocalRef(env, hab);
return result;
} }
(*env)->DeleteLocalRef(env, hab);
return result;
} }
return 0; return NULL;
} }
JNIEXPORT const char * JNIEXPORT const char *
...@@ -768,46 +767,49 @@ GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy) ...@@ -768,46 +767,49 @@ GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy)
JNIEXPORT const char * JNICALL JNIEXPORT const char * JNICALL
JNU_GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy) JNU_GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy)
{ {
jbyteArray hab = 0; char *result = nativeGetStringPlatformChars(env, jstr, isCopy);
char *result = 0; if (result == NULL) {
if (isCopy) jbyteArray hab = 0;
*isCopy = JNI_TRUE;
if (fastEncoding == NO_ENCODING_YET) if (isCopy)
initializeEncoding(env); *isCopy = JNI_TRUE;
if ((fastEncoding == FAST_8859_1) || (fastEncoding == NO_ENCODING_YET)) if (fastEncoding == NO_ENCODING_YET)
return getString8859_1Chars(env, jstr); initializeEncoding(env);
if (fastEncoding == FAST_646_US)
return getString646_USChars(env, jstr);
if (fastEncoding == FAST_CP1252)
return getStringCp1252Chars(env, jstr);
if ((*env)->EnsureLocalCapacity(env, 2) < 0) if ((fastEncoding == FAST_8859_1) || (fastEncoding == NO_ENCODING_YET))
return 0; return getString8859_1Chars(env, jstr);
if (fastEncoding == FAST_646_US)
if (jnuEncodingSupported(env)) { return getString646_USChars(env, jstr);
hab = (*env)->CallObjectMethod(env, jstr, String_getBytes_ID, jnuEncoding); if (fastEncoding == FAST_CP1252)
} else { return getStringCp1252Chars(env, jstr);
jmethodID mid = (*env)->GetMethodID(env, JNU_ClassString(env),
"getBytes", "()[B");
hab = (*env)->CallObjectMethod(env, jstr, mid);
}
if (!(*env)->ExceptionCheck(env)) { if ((*env)->EnsureLocalCapacity(env, 2) < 0)
jint len = (*env)->GetArrayLength(env, hab);
result = MALLOC_MIN4(len);
if (result == 0) {
JNU_ThrowOutOfMemoryError(env, 0);
(*env)->DeleteLocalRef(env, hab);
return 0; return 0;
if (jnuEncodingSupported(env)) {
hab = (*env)->CallObjectMethod(env, jstr, String_getBytes_ID, jnuEncoding);
} else {
jmethodID mid = (*env)->GetMethodID(env, JNU_ClassString(env),
"getBytes", "()[B");
hab = (*env)->CallObjectMethod(env, jstr, mid);
}
if (!(*env)->ExceptionCheck(env)) {
jint len = (*env)->GetArrayLength(env, hab);
result = MALLOC_MIN4(len);
if (result == 0) {
JNU_ThrowOutOfMemoryError(env, 0);
(*env)->DeleteLocalRef(env, hab);
return 0;
}
(*env)->GetByteArrayRegion(env, hab, 0, len, (jbyte *)result);
result[len] = 0; /* NULL-terminate */
} }
(*env)->GetByteArrayRegion(env, hab, 0, len, (jbyte *)result);
result[len] = 0; /* NULL-terminate */
}
(*env)->DeleteLocalRef(env, hab); (*env)->DeleteLocalRef(env, hab);
}
return result; return result;
} }
......
...@@ -320,6 +320,26 @@ JNU_GetEnv(JavaVM *vm, jint version); ...@@ -320,6 +320,26 @@ JNU_GetEnv(JavaVM *vm, jint version);
#define JNU_SetLongFieldFromPtr(env,obj,id,val) \ #define JNU_SetLongFieldFromPtr(env,obj,id,val) \
(*(env))->SetLongField((env),(obj),(id),ptr_to_jlong(val)) (*(env))->SetLongField((env),(obj),(id),ptr_to_jlong(val))
/*
* Internal use only.
*/
enum {
NO_ENCODING_YET = 0, /* "sun.jnu.encoding" not yet set */
NO_FAST_ENCODING, /* Platform encoding is not fast */
FAST_8859_1, /* ISO-8859-1 */
FAST_CP1252, /* MS-DOS Cp1252 */
FAST_646_US /* US-ASCII : ISO646-US */
};
jstring nativeNewStringPlatform(JNIEnv *env, const char *str);
char* nativeGetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy);
int getFastEncoding();
void initializeEncoding();
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */
#endif /* __cplusplus */ #endif /* __cplusplus */
......
...@@ -109,11 +109,39 @@ Java_sun_misc_VM_getThreadStateValues(JNIEnv *env, jclass cls, ...@@ -109,11 +109,39 @@ Java_sun_misc_VM_getThreadStateValues(JNIEnv *env, jclass cls,
get_thread_state_info(env, JAVA_THREAD_STATE_TERMINATED, values, names); get_thread_state_info(env, JAVA_THREAD_STATE_TERMINATED, values, names);
} }
typedef void (JNICALL *GetJvmVersionInfo_fp)(JNIEnv*, jvm_version_info*, size_t);
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_sun_misc_VM_initialize(JNIEnv *env, jclass cls) { Java_sun_misc_VM_initialize(JNIEnv *env, jclass cls) {
char errmsg[128]; char errmsg[128];
GetJvmVersionInfo_fp func_p;
if (!JDK_InitJvmHandle()) { if (!JDK_InitJvmHandle()) {
JNU_ThrowInternalError(env, "Handle for JVM not found for symbol lookup"); JNU_ThrowInternalError(env, "Handle for JVM not found for symbol lookup");
return;
}
func_p = (GetJvmVersionInfo_fp) JDK_FindJvmEntry("JVM_GetVersionInfo");
if (func_p != NULL) {
char errmsg[100];
jfieldID fid;
jvm_version_info info;
memset(&info, 0, sizeof(info));
/* obtain the JVM version info */
(*func_p)(env, &info, sizeof(info));
if (info.is_kernel_jvm == 1) {
/* set the static field VM.kernelVM to true for kernel VM */
fid = (*env)->GetStaticFieldID(env, cls, "kernelVM", "Z");
if (fid != 0) {
(*env)->SetStaticBooleanField(env, cls, fid, info.is_kernel_jvm);
} else {
sprintf(errmsg, "Static kernelVM boolean field not found");
JNU_ThrowInternalError(env, errmsg);
}
}
} }
} }
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
#include "jni.h"
#include "jni_util.h"
jstring nativeNewStringPlatform(JNIEnv *env, const char *str) {
return NULL;
}
char* nativeGetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy) {
return NULL;
}
...@@ -49,6 +49,7 @@ static jboolean GetPublicJREHome(char *path, jint pathsize); ...@@ -49,6 +49,7 @@ static jboolean GetPublicJREHome(char *path, jint pathsize);
static jboolean GetJVMPath(const char *jrepath, const char *jvmtype, static jboolean GetJVMPath(const char *jrepath, const char *jvmtype,
char *jvmpath, jint jvmpathsize); char *jvmpath, jint jvmpathsize);
static jboolean GetJREPath(char *path, jint pathsize); static jboolean GetJREPath(char *path, jint pathsize);
static void EnsureJreInstallation(const char *jrepath);
static jboolean _isjavaw = JNI_FALSE; static jboolean _isjavaw = JNI_FALSE;
...@@ -108,6 +109,9 @@ CreateExecutionEnvironment(int *_argc, ...@@ -108,6 +109,9 @@ CreateExecutionEnvironment(int *_argc,
exit(1); exit(1);
} }
/* Do this before we read jvm.cfg */
EnsureJreInstallation(jrepath);
/* Find out where the JRE is that we will be using. */ /* Find out where the JRE is that we will be using. */
if (!GetJREPath(jrepath, so_jrepath)) { if (!GetJREPath(jrepath, so_jrepath)) {
JLI_ReportErrorMessage(JRE_ERROR1); JLI_ReportErrorMessage(JRE_ERROR1);
...@@ -130,6 +134,103 @@ CreateExecutionEnvironment(int *_argc, ...@@ -130,6 +134,103 @@ CreateExecutionEnvironment(int *_argc,
} }
static jboolean
LoadMSVCRT()
{
// Only do this once
static int loaded = 0;
char crtpath[MAXPATHLEN];
if (!loaded) {
/*
* The Microsoft C Runtime Library needs to be loaded first. A copy is
* assumed to be present in the "JRE path" directory. If it is not found
* there (or "JRE path" fails to resolve), skip the explicit load and let
* nature take its course, which is likely to be a failure to execute.
*/
#ifdef _MSC_VER
#if _MSC_VER < 1400
#define CRT_DLL "msvcr71.dll"
#endif
#ifdef CRT_DLL
if (GetJREPath(crtpath, MAXPATHLEN)) {
(void)JLI_StrCat(crtpath, "\\bin\\" CRT_DLL); /* Add crt dll */
JLI_TraceLauncher("CRT path is %s\n", crtpath);
if (_access(crtpath, 0) == 0) {
if (LoadLibrary(crtpath) == 0) {
JLI_ReportErrorMessage(DLL_ERROR4, crtpath);
return JNI_FALSE;
}
}
}
#endif /* CRT_DLL */
#endif /* _MSC_VER */
loaded = 1;
}
return JNI_TRUE;
}
/*
* The preJVMStart is a function in the jkernel.dll, which
* performs the final step of synthesizing back the decomposed
* modules (partial install) to the full JRE. Any tool which
* uses the JRE must peform this step to ensure the complete synthesis.
* The EnsureJreInstallation function calls preJVMStart based on
* the conditions outlined below, noting that the operation
* will fail silently if any of conditions are not met.
* NOTE: this call must be made before jvm.dll is loaded, or jvm.cfg
* is read, since jvm.cfg will be modified by the preJVMStart.
* 1. Are we on a supported platform.
* 2. Find the location of the JRE or the Kernel JRE.
* 3. check existence of JREHOME/lib/bundles
* 4. check jkernel.dll and invoke the entry-point
*/
typedef VOID (WINAPI *PREJVMSTART)();
static void
EnsureJreInstallation(const char* jrepath)
{
HINSTANCE handle;
char tmpbuf[MAXPATHLEN];
PREJVMSTART PreJVMStart;
struct stat s;
/* 32 bit windows only please */
if (strcmp(GetArch(), "i386") != 0 ) {
return;
}
/* Does our bundle directory exist ? */
strcpy(tmpbuf, jrepath);
strcat(tmpbuf, "\\lib\\bundles");
if (stat(tmpbuf, &s) != 0) {
return;
}
/* Does our jkernel dll exist ? */
strcpy(tmpbuf, jrepath);
strcat(tmpbuf, "\\bin\\jkernel.dll");
if (stat(tmpbuf, &s) != 0) {
return;
}
/* The Microsoft C Runtime Library needs to be loaded first. */
if (!LoadMSVCRT()) {
return;
}
/* Load the jkernel.dll */
if ((handle = LoadLibrary(tmpbuf)) == 0) {
return;
}
/* Get the function address */
PreJVMStart = (PREJVMSTART)GetProcAddress(handle, "preJVMStart");
if (PreJVMStart == NULL) {
FreeLibrary(handle);
return;
}
PreJVMStart();
FreeLibrary(handle);
return;
}
/* /*
* Find path to JRE based on .exe's location or registry settings. * Find path to JRE based on .exe's location or registry settings.
*/ */
...@@ -196,7 +297,6 @@ jboolean ...@@ -196,7 +297,6 @@ jboolean
LoadJavaVM(const char *jvmpath, InvocationFunctions *ifn) LoadJavaVM(const char *jvmpath, InvocationFunctions *ifn)
{ {
HINSTANCE handle; HINSTANCE handle;
char crtpath[MAXPATHLEN];
JLI_TraceLauncher("JVM path is %s\n", jvmpath); JLI_TraceLauncher("JVM path is %s\n", jvmpath);
...@@ -206,26 +306,8 @@ LoadJavaVM(const char *jvmpath, InvocationFunctions *ifn) ...@@ -206,26 +306,8 @@ LoadJavaVM(const char *jvmpath, InvocationFunctions *ifn)
* there (or "JRE path" fails to resolve), skip the explicit load and let * there (or "JRE path" fails to resolve), skip the explicit load and let
* nature take its course, which is likely to be a failure to execute. * nature take its course, which is likely to be a failure to execute.
* *
* (NOTE: the above statement is only true for Visual Studio 2003 and
* msvcr71.dll.)
*/ */
#ifdef _MSC_VER LoadMSVCRT();
#if _MSC_VER < 1400
#define CRT_DLL "msvcr71.dll"
#endif
#ifdef CRT_DLL
if (GetJREPath(crtpath, MAXPATHLEN)) {
(void)JLI_StrCat(crtpath, "\\bin\\" CRT_DLL); /* Add crt dll */
JLI_TraceLauncher("CRT path is %s\n", crtpath);
if (_access(crtpath, 0) == 0) {
if (LoadLibrary(crtpath) == 0) {
JLI_ReportErrorMessage(DLL_ERROR4, crtpath);
return JNI_FALSE;
}
}
}
#endif /* CRT_DLL */
#endif /* _MSC_VER */
/* Load the Java VM DLL */ /* Load the Java VM DLL */
if ((handle = LoadLibrary(jvmpath)) == 0) { if ((handle = LoadLibrary(jvmpath)) == 0) {
......
/*
* Copyright 2004 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <locale.h>
#include "jni.h"
#include "jni_util.h"
static void getParent(const TCHAR *path, TCHAR *dest) {
char* lastSlash = max(strrchr(path, '\\'), strrchr(path, '/'));
if (lastSlash == NULL) {
*dest = 0;
return;
}
if (path != dest)
strcpy(dest, path);
*lastSlash = 0;
}
BOOL useNativeConverter(JNIEnv *env) {
static BOOL initialized;
static BOOL useNative;
if (!initialized) {
HMODULE jvm = GetModuleHandle("jvm");
useNative = FALSE;
if (jvm != NULL) {
TCHAR *jvmPath = NULL;
int bufferSize = MAX_PATH;
while (jvmPath == NULL) {
DWORD result;
jvmPath = malloc(bufferSize);
if (jvmPath == NULL)
return FALSE;
result = GetModuleFileName(jvm, jvmPath, bufferSize);
if (result == 0)
return FALSE;
if (result == bufferSize) { // didn't fit
bufferSize += MAX_PATH; // increase buffer size, try again
free(jvmPath);
jvmPath = NULL;
}
}
getParent(jvmPath, jvmPath);
useNative = (!strcmp("kernel", jvmPath + strlen(jvmPath) -
strlen("kernel"))); // true if jvm.dll lives in "kernel"
if (useNative)
setlocale(LC_ALL, "");
free(jvmPath);
}
initialized = TRUE;
}
return useNative;
}
jstring nativeNewStringPlatform(JNIEnv *env, const char *str) {
static String_char_constructor = NULL;
if (useNativeConverter(env)) {
// use native Unicode conversion so Kernel isn't required during
// System.initProperties
jcharArray chars = 0;
wchar_t *utf16;
int len;
jstring result = NULL;
if (getFastEncoding() == NO_ENCODING_YET)
initializeEncoding(env);
len = mbstowcs(NULL, str, strlen(str));
if (len == -1)
return NULL;
utf16 = calloc(len + 1, 2);
if (mbstowcs(utf16, str, len) == -1)
return NULL;
chars = (*env)->NewCharArray(env, len);
if (chars == NULL)
return NULL;
(*env)->SetCharArrayRegion(env, chars, 0, len, utf16);
if (String_char_constructor == NULL)
String_char_constructor = (*env)->GetMethodID(env,
JNU_ClassString(env), "<init>", "([C)V");
result = (*env)->NewObject(env, JNU_ClassString(env),
String_char_constructor, chars);
free(utf16);
return result;
}
else
return NULL;
}
char* nativeGetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy) {
if (useNativeConverter(env)) {
// use native Unicode conversion so Kernel isn't required during
// System.initProperties
char *result = NULL;
size_t len;
const jchar* utf16 = (*env)->GetStringChars(env, jstr, NULL);
len = wcstombs(NULL, utf16, (*env)->GetStringLength(env, jstr) * 4) + 1;
if (len == -1)
return NULL;
result = (char*) malloc(len);
if (result != NULL) {
if (wcstombs(result, utf16, len) == -1)
return NULL;
(*env)->ReleaseStringChars(env, jstr, utf16);
if (isCopy)
*isCopy = JNI_TRUE;
}
return result;
}
else
return NULL;
}
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define STRICT
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif
#define _ATL_APARTMENT_THREADED
#include <atlbase.h>
//You may derive a class from CComModule and use it if you want to override
//something, but do not change the name of _Module
extern CComModule _Module;
#include <atlcom.h>
#include <atlwin.h>
#include <atlhost.h>
#include <commdlg.h>
#include <commctrl.h>
#include <windowsx.h>
#include <urlmon.h>
#include <wininet.h>
#include <shellapi.h>
#include <time.h>
#include <math.h>
#include <stdio.h>
#include <jni.h>
#include "DownloadDialog.h"
#define UPDATE_INTERVAL 500
#define INITIAL_DELAY 2000
#define POST_DELAY 1000
/////////////////////////////////////////////////////////////////////////////
// CDownloadDialog
typedef BOOL (WINAPI * InitCommonControlsType)();
CDownloadDialog::CDownloadDialog()
{
m_numDownloadThreadsRunning = 0;
m_destroyWindowTimerStarted = FALSE;
m_pszFileName = NULL;
m_jvm = NULL;
m_ulProgress = 0;
m_ulProgressMax = 0;
m_iProgressFactor = 0;
m_iMaxProgressFactor = 1;
m_hCancelEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
m_hDownloadThreadExitEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
m_hDialogInitializedEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
// Load up commctrl.dll
// Loading dll dynamically we can use latest available version
// (i.e. latest native components and extended API)
HMODULE hModComCtl32 = ::LoadLibrary(TEXT("comctl32.dll"));
if (hModComCtl32 != NULL) {
/* Initialize controls to ensure proper appearance */
InitCommonControlsType fn_InitCommonControls = (InitCommonControlsType)
::GetProcAddress(hModComCtl32, "InitCommonControls");
fn_InitCommonControls();
/* MessageBox replacement introduced in Vista */
taskDialogFn = (TaskDialogIndirectFn)
::GetProcAddress(hModComCtl32, "TaskDialogIndirect");
}
}
CDownloadDialog::~CDownloadDialog()
{
::CloseHandle(m_hCancelEvent);
::CloseHandle(m_hDownloadThreadExitEvent);
::CloseHandle(m_hDialogInitializedEvent);
}
void CDownloadDialog::addToTotalContentLength(DWORD contentLength) {
__try
{
m_csDownload.Lock();
if (m_ulProgressMax == 0) {
// first download this session, initialize start time
time(&m_startTime);
}
m_ulProgressMax = m_ulProgressMax + contentLength;
logProgress();
}
__finally
{
m_csDownload.Unlock();
}
}
void CDownloadDialog::initDialogText(LPCTSTR downloadURL, LPCTSTR bundleName) {
// reset status text
HWND hStatusWnd = GetDlgItem(IDC_TIME_REMAINING);
::SetWindowText(hStatusWnd, "");
// reset progress bar
HWND hProgressWnd = GetDlgItem(IDC_DOWNLOAD_PROGRESS);
::PostMessage(hProgressWnd, PBM_SETPOS, (WPARAM) 0, NULL);
m_hMastheadFont = NULL;
m_hDialogFont = NULL;
m_hSixPointFont = NULL;
m_hMemDC = NULL;
TCHAR szDownloadText[BUFFER_SIZE];
HWND hWndDownloadText = GetDlgItem(IDC_DOWNLOAD_TEXT);
::LoadString(_Module.GetModuleInstance(), IDS_DOWNLOAD_TEXT, szDownloadText, BUFFER_SIZE);
::SetWindowText(hWndDownloadText, szDownloadText);
TCHAR szMasthead[BUFFER_SIZE];
HWND hWndMastheadText = GetDlgItem(IDC_MASTHEAD_TEXT);
::LoadString(_Module.GetModuleInstance(), IDS_DOWNLOAD, szMasthead, BUFFER_SIZE);
::SetWindowText(hWndMastheadText, szMasthead);
}
BOOL CDownloadDialog::isDownloading() {
return m_numDownloadThreadsRunning > 0;
}
void CDownloadDialog::bundleInstallStart() {
__try
{
m_csNumDownloadThreads.Lock();
m_numDownloadThreadsRunning++;
// another download request has came in, kill the destroyWindowTimer
KillTimer(destroyWindowTimerID);
m_destroyWindowTimerStarted = FALSE;
}
__finally
{
m_csNumDownloadThreads.Unlock();
}
}
void CDownloadDialog::bundleInstallComplete() {
__try
{
m_csNumDownloadThreads.Lock();
m_numDownloadThreadsRunning = max(m_numDownloadThreadsRunning - 1, 0);
if (m_numDownloadThreadsRunning == 0) {
m_ulProgress = m_ulProgressMax;
logProgress();
}
// Signal main thread
::SetEvent(m_hDownloadThreadExitEvent);
}
__finally
{
m_csNumDownloadThreads.Unlock();
}
}
//=--------------------------------------------------------------------------=
// CDownloadDialog::OnInitDialog
//=--------------------------------------------------------------------------=
// Message handler for WM_INITDIALOG
//
// Parameters:
// uMsg Windows Message
// wParam WPARAM
// lParam LPARAM
// bHandled FALSE if not handled
//
// Output:
// LRESULT
//
// Notes:
//
LRESULT CDownloadDialog::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
__try
{
m_csDownload.Lock();
}
__finally
{
m_csDownload.Unlock();
}
// Set timer
SetTimer(iTimerID, UPDATE_INTERVAL);
m_hMastheadFont = NULL;
m_hDialogFont = NULL;
m_hSixPointFont = NULL;
m_feedbackOnCancel = TRUE;
m_hMemDC = NULL;
TCHAR szDownloadText[BUFFER_SIZE];
HWND hWndDownloadText = GetDlgItem(IDC_DOWNLOAD_TEXT);
::LoadString(_Module.GetModuleInstance(), IDS_DOWNLOAD_TEXT, szDownloadText, BUFFER_SIZE);
::SetWindowText(hWndDownloadText, szDownloadText);
TCHAR szMasthead[BUFFER_SIZE];
HWND hWndMastheadText = GetDlgItem(IDC_MASTHEAD_TEXT);
::LoadString(_Module.GetModuleInstance(), IDS_DOWNLOAD, szMasthead, BUFFER_SIZE);
::SetWindowText(hWndMastheadText, szMasthead);
HICON javaCupIcon = ::LoadIcon(_Module.GetModuleInstance(), MAKEINTRESOURCE(IDI_JAVA));
SetIcon(javaCupIcon, FALSE);
::SetEvent(m_hDialogInitializedEvent);
return 0; // do not set initial focus to cancel button
}
//=--------------------------------------------------------------------------=
// CDownloadDialog::OnOK
//=--------------------------------------------------------------------------=
// Message handler for WM_COMMAND with IDOK
//
// Parameters:
// wNotifyCode Notify Code
// wID ID of control
// hWndCtl HWND of control
// bHandled FALSE if not handled
//
// Output:
// LRESULT
//
// Notes:
//
LRESULT CDownloadDialog::OnOK(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
// do nothing for now
return 0;
}
//=--------------------------------------------------------------------------=
// CDownloadDialog::OnCancel
//=--------------------------------------------------------------------------=
// Message handler for WM_COMMAND with IDCANCEL
//
// Parameters:
// wNotifyCode Notify Code
// wID ID of control
// hWndCtl HWND of control
// bHandled FALSE if not handled
//
// Output:
// LRESULT
//
// Notes:
//
LRESULT CDownloadDialog::OnCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
// Disable window first to avoid any keyboard input
EnableWindow(FALSE);
if (m_feedbackOnCancel) {
int r = SafeMessageBox(IDS_DOWNLOAD_CANCEL_MESSAGE,
IDS_DOWNLOAD_CANCEL_INSTRUCTION,
IDS_DOWNLOAD_CANCEL_CAPTION,
DIALOG_WARNING_CANCELOK,
NULL, NULL);
if (!::IsWindow(hWndCtl)) {
/* It is possible that download was finished and download
window hidden by the time user close this message box.
If such case we should simply return. */
return 0;
}
if (r == IDCANCEL) {
EnableWindow(TRUE);
return 0;
}
}
__try
{
m_csDownload.Lock();
// if we are downloading, signal download thread to stop downloading
if (m_numDownloadThreadsRunning > 0) {
SetEvent(m_hCancelEvent);
}
}
__finally
{
m_csDownload.Unlock();
}
// Kill timer
KillTimer(iTimerID);
KillTimer(destroyWindowTimerID);
FreeGDIResources();
// Destroy dialog
EndDialog(wID);
return 0;
}
void CDownloadDialog::destroyDialog() {
m_feedbackOnCancel = FALSE;
::PostMessage(m_hWnd, WM_COMMAND, IDCANCEL, NULL);
}
void CDownloadDialog::delayedDoModal() {
__try
{
__try
{
m_csMessageBox.Lock();
m_dialogUp = true;
Sleep(INITIAL_DELAY);
}
__finally
{
m_csMessageBox.Unlock();
}
if (isDownloading())
DoModal();
}
__finally
{
m_dialogUp = false;
}
}
//=--------------------------------------------------------------------------=
// CDownloadDialog::SafeMessageBox
//=--------------------------------------------------------------------------=
// Helper method that uses best availble API to show native error/information
// dialog. In particular, it uses TaskDialog if availble (Vista specific)
// and MessageBox otherwise.
//
// It also ensures that the message box is always displayed on top of
// the progress dialog instead of underneath
//
//helper structures to define XP vs Vista style differences
static TASKDIALOG_COMMON_BUTTON_FLAGS vistaDialogButtons[] = {
TDCBF_RETRY_BUTTON | TDCBF_CANCEL_BUTTON,
TDCBF_OK_BUTTON | TDCBF_CANCEL_BUTTON
};
static PCWSTR vistaIcons[] = {
TD_ERROR_ICON,
TD_WARNING_ICON
};
static UINT xpStyle[] = {
MB_ICONERROR | MB_RETRYCANCEL,
MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2
};
int CDownloadDialog::SafeMessageBox(UINT details, UINT mainInstruction, UINT caption, DialogType type, LPCWSTR instructionArg, LPCWSTR detailsArg) {
WCHAR textCaption[BUFFER_SIZE+1];
WCHAR textDetails[BUFFER_SIZE+1];
WCHAR textInstruction[BUFFER_SIZE+1];
WCHAR tmpBuffer[BUFFER_SIZE+1];
/* make sure buffers are terminated */
textCaption[BUFFER_SIZE] = textDetails[BUFFER_SIZE] = 0;
textInstruction[BUFFER_SIZE] = tmpBuffer[BUFFER_SIZE] = 0;
if (detailsArg != NULL) {
::LoadStringW(_Module.GetResourceInstance(),
details,
tmpBuffer,
BUFFER_SIZE);
_snwprintf(textDetails, BUFFER_SIZE, tmpBuffer, detailsArg);
} else {
::LoadStringW(_Module.GetResourceInstance(),
details,
textDetails,
BUFFER_SIZE);
}
if (instructionArg != NULL) {
::LoadStringW(_Module.GetResourceInstance(),
mainInstruction,
tmpBuffer,
BUFFER_SIZE);
_snwprintf(textInstruction, BUFFER_SIZE, tmpBuffer, instructionArg);
} else {
::LoadStringW(_Module.GetResourceInstance(),
mainInstruction,
textInstruction,
BUFFER_SIZE);
}
::LoadStringW(_Module.GetResourceInstance(),
caption,
textCaption,
BUFFER_SIZE);
__try
{
m_csMessageBox.Lock();
if (m_dialogUp) {
waitUntilInitialized();
}
/* If TaskDialog availble - use it! */
if (taskDialogFn != NULL) {
TASKDIALOGCONFIG tc = { 0 };
int nButton;
tc.cbSize = sizeof(tc);
tc.hwndParent = ::IsWindow(m_hWnd) ? m_hWnd : NULL;
tc.dwCommonButtons = vistaDialogButtons[type];
tc.pszWindowTitle = textCaption;
tc.pszMainInstruction = textInstruction;
tc.pszContent = textDetails;
tc.pszMainIcon = vistaIcons[type];
/* workaround: we need to make sure Cancel is default
for this type of Dialog */
if (type == DIALOG_WARNING_CANCELOK) {
tc.nDefaultButton = IDCANCEL;
}
taskDialogFn(&tc, &nButton, NULL, NULL);
return nButton;
} else { /* default: use MessageBox */
/* Note that MessageBox API expects content as single string
and therefore we need to concatenate instruction
and details as 2 paragraphs.
The only exception is empty instruction. */
if (wcslen(textInstruction) > 0) {
wcsncat(textInstruction, L"\n\n",
BUFFER_SIZE - wcslen(textInstruction));
}
wcsncat(textInstruction, textDetails,
BUFFER_SIZE - wcslen(textInstruction));
return ::MessageBoxW(::IsWindow(m_hWnd) ? m_hWnd : NULL,
textInstruction, textCaption, xpStyle[type]);
}
}
__finally
{
m_csMessageBox.Unlock();
}
}
//=--------------------------------------------------------------------------=
// CDownloadDialog::OnTimer
//=--------------------------------------------------------------------------=
// Message handler for WM_TIMER
//
// Parameters:
// uMsg Windows Message
// wParam WPARAM
// lParam LPARAM
// bHandled FALSE if not handled
//
// Output:
// LRESULT
//
// Notes:
//
LRESULT CDownloadDialog::OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if (destroyWindowTimerID == (int)wParam) {
KillTimer(destroyWindowTimerID);
m_destroyWindowTimerStarted = FALSE;
m_ulProgressMax = max(0, m_ulProgressMax - m_ulProgress);
logProgress();
m_ulProgress = 0;
logProgress();
m_feedbackOnCancel = FALSE;
::PostMessage(m_hWnd, WM_COMMAND, IDCANCEL, NULL);
}
if (iTimerID == (int)wParam)
{
__try
{
m_csDownload.Lock();
HWND hStatusWnd = GetDlgItem(IDC_TIME_REMAINING);
HWND hProgressWnd = GetDlgItem(IDC_DOWNLOAD_PROGRESS);
if (m_ulProgress && m_ulProgressMax)
{
::PostMessage(hProgressWnd, PBM_SETPOS,
(WPARAM) (m_ulProgress * 100
/ m_ulProgressMax), NULL);
time_t currentTime;
time(&currentTime);
double elapsed_time = difftime(currentTime, m_startTime);
double remain_time = (elapsed_time / m_ulProgress) *
(m_ulProgressMax - m_ulProgress);
int hr = 0, min = 0;
if (remain_time > 60 * 60)
{
hr = int(remain_time / (60 * 60));
remain_time = remain_time - hr * 60 * 60;
}
if (remain_time > 60)
{
min = int(remain_time / 60);
remain_time = remain_time - min * 60;
}
TCHAR szBuffer[BUFFER_SIZE];
TCHAR szTimeBuffer[BUFFER_SIZE];
if (hr > 0)
{
if (hr > 1)
LoadString(_Module.GetResourceInstance(), IDS_HOURSMINUTESECOND,
szTimeBuffer, BUFFER_SIZE);
else
LoadString(_Module.GetResourceInstance(), IDS_HOURMINUTESECOND,
szTimeBuffer, BUFFER_SIZE);
sprintf(szBuffer, szTimeBuffer, hr, min, remain_time);
}
else
{
if (min > 0)
{
LoadString(_Module.GetResourceInstance(), IDS_MINUTESECOND,
szTimeBuffer, BUFFER_SIZE);
sprintf(szBuffer, szTimeBuffer, min, remain_time);
}
else
{
LoadString(_Module.GetResourceInstance(), IDS_SECOND,
szTimeBuffer, BUFFER_SIZE);
sprintf(szBuffer, szTimeBuffer, remain_time);
}
}
if (m_ulProgress == m_ulProgressMax) {
// download is done, unpacking bundle now, and waiting
// for another download to take place
::LoadString(_Module.GetResourceInstance(),
IDS_DOWNLOAD_UNPACKING, szBuffer, BUFFER_SIZE);
__try
{
m_csNumDownloadThreads.Lock();
// both download and unpacking is done, start
// timer to destroy the progress window in 500ms
if (!m_destroyWindowTimerStarted &&
m_numDownloadThreadsRunning == 0) {
SetTimer(destroyWindowTimerID, POST_DELAY);
m_destroyWindowTimerStarted = TRUE;
}
}
__finally
{
m_csNumDownloadThreads.Unlock();
}
}
// Update status message
::SetWindowText(hStatusWnd, szBuffer);
}
}
__finally
{
m_csDownload.Unlock();
}
}
return 0;
}
// Message handler for WM_ONCTLCOLORSTATIC.
// this message is sent each time a static control is drawn.
// we get the Control ID and then set background color and font
// as appropriate for that control.
LRESULT CDownloadDialog::OnCtlColorStatic(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
HDC hdc = (HDC) wParam;
HWND hwnd = (HWND) lParam;
int DlgCtrlID = ::GetDlgCtrlID(hwnd);
if (DlgCtrlID == IDC_DOWNLOAD_TEXT )
{
if (m_hDialogFont == NULL)
{
m_hDialogFont = CreateDialogFont(hdc, TEXT("MS Shell Dlg"), 8);
}
::SelectObject(hdc, m_hDialogFont);
return 0;
}
else if (DlgCtrlID == IDC_TIME_REMAINING)
{
if (m_hSixPointFont == NULL)
{
m_hSixPointFont = CreateDialogFont(hdc, TEXT("MS Shell Dlg"), 8);
}
::SelectObject(hdc, m_hSixPointFont);
return 0;
}
else if (DlgCtrlID == IDC_MASTHEAD_TEXT)
{
if (m_hMastheadFont == NULL)
{
m_hMastheadFont = CreateDialogFont(hdc, TEXT("MS Shell Dlg"), 12, 1);
}
::SelectObject(hdc, m_hMastheadFont);
return (LRESULT) GetStockObject(WHITE_BRUSH);
}
else if (DlgCtrlID == IDC_DOWNLOAD_MASTHEAD)
{
if (m_hMemDC == NULL)
{
m_hBitmap = LoadBitmap(_Module.GetModuleInstance(),
MAKEINTRESOURCE(IDI_MASTHEAD));
GetObject(m_hBitmap, sizeof(BITMAP), &m_bmMasthead);
m_hMemDC = CreateCompatibleDC(NULL);
SelectObject(m_hMemDC, m_hBitmap);
}
RECT rect;
::GetClientRect(hwnd, &rect);
StretchBlt(hdc, rect.left, rect.top, (rect.right - rect.left), (rect.bottom - rect.top),
m_hMemDC, 0, 0, m_bmMasthead.bmWidth, m_bmMasthead.bmHeight, SRCCOPY);
return (LRESULT) GetStockObject(NULL_BRUSH);
}
return 0;
}
//=--------------------------------------------------------------------------=
// CDownloadDialog::OnStartBinding
//=--------------------------------------------------------------------------=
// Called when download is started
//
// Parameters:
//
// Output:
// HRESULT
//
// Notes:
//
STDMETHODIMP CDownloadDialog::OnStartBinding()
{
__try
{
m_csDownload.Lock();
time(&m_startTime);
}
__finally
{
m_csDownload.Unlock();
}
return S_OK;
}
//=--------------------------------------------------------------------------=
// CDownloadDialog::OnProgress
//=--------------------------------------------------------------------------=
// Called when download is in progress
//
// Parameters: ULONG ulProgress
//
// Output:
// HRESULT
//
// Notes:
//
STDMETHODIMP CDownloadDialog::OnProgress(ULONG ulProgress)
{
__try
{
m_csDownload.Lock();
m_ulProgress = m_ulProgress + ulProgress;
logProgress();
}
__finally
{
m_csDownload.Unlock();
}
return S_OK;
}
void CDownloadDialog::decrementProgressMax(ULONG contentLength, ULONG readSoFar) {
__try
{
m_csDownload.Lock();
m_ulProgressMax = m_ulProgressMax - contentLength;
m_ulProgress = m_ulProgress - readSoFar;
logProgress();
}
__finally
{
m_csDownload.Unlock();
}
}
void CDownloadDialog::waitUntilInitialized() {
// wait until download progress dialog is initialized and ready to show
WaitForSingleObject(m_hDialogInitializedEvent, INFINITE);
ResetEvent(m_hDialogInitializedEvent);
}
// Check if download has been cancelled
BOOL CDownloadDialog::isDownloadCancelled() {
if (WAIT_OBJECT_0 == WaitForSingleObject(m_hCancelEvent, 0)) {
return TRUE;
}
return FALSE;
}
// Create the fonts we need for the download and
// install UE
HFONT CDownloadDialog::CreateDialogFont(HDC hdc, LPCTSTR lpszFaceName, int ptSize, int isBold)
{
POINT pt;
FLOAT cxDPI, cyDPI;
HFONT hFont;
LOGFONT lf;
int iDeciPtWidth = 0;
int iDeciPtHeight = 10 * ptSize;
int iSavedDC = SaveDC(hdc);
SetGraphicsMode (hdc, GM_ADVANCED);
ModifyWorldTransform(hdc, NULL, MWT_IDENTITY);
SetViewportOrgEx (hdc, 0,0, NULL);
SetWindowOrgEx (hdc, 0,0, NULL);
cxDPI = (FLOAT) GetDeviceCaps(hdc, LOGPIXELSX);
cyDPI = (FLOAT) GetDeviceCaps(hdc, LOGPIXELSY);
pt.x = (int) (iDeciPtWidth * cxDPI / 72);
pt.y = (int) (iDeciPtHeight * cyDPI / 72);
DPtoLP(hdc, &pt, 1);
lf.lfHeight = - (int) (fabs ((double) pt.y) / 10.0 + 0.5);
lf.lfWidth = 0;
lf.lfEscapement = 0;
lf.lfOrientation = 0;
lf.lfWeight = (isBold > 0) ? FW_BOLD : 0;
lf.lfItalic = 0;
lf.lfUnderline = 0;
lf.lfStrikeOut = 0;
lf.lfCharSet = 0;
lf.lfOutPrecision = 0;
lf.lfClipPrecision = 0;
lf.lfQuality = 0;
lf.lfPitchAndFamily = 0;
TCHAR szLocaleData[BUFFER_SIZE];
GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SENGCOUNTRY,
szLocaleData, BUFFER_SIZE);
if (strncmp(szLocaleData, "Japan", 5) == 0) {
// need special font for _ja locale
strcpy (lf.lfFaceName, TEXT("MS UI Gothic"));
} else {
strcpy (lf.lfFaceName, lpszFaceName);
}
hFont = CreateFontIndirect(&lf);
RestoreDC (hdc, iSavedDC);
return hFont;
}
void CDownloadDialog::FreeGDIResources ()
{
::DeleteObject(m_hMastheadFont);
m_hMastheadFont = NULL;
::DeleteObject(m_hDialogFont);
m_hDialogFont = NULL;
::DeleteObject(m_hSixPointFont);
m_hSixPointFont = NULL;
::DeleteObject(m_hBitmap);
m_hBitmap = NULL;
::DeleteDC(m_hMemDC);
m_hMemDC = NULL;
}
JNIEnv* CDownloadDialog::getJNIEnv() {
if (m_jvm == NULL)
return NULL;
JNIEnv *env;
m_jvm->AttachCurrentThread((void**) &env, NULL);
return env;
}
void CDownloadDialog::log(char *msg) {
JNIEnv *env = getJNIEnv();
if (env != NULL) {
jclass dm = env->FindClass("sun/jkernel/DownloadManager");
if (dm == NULL) {
printf("Cound not find class sun.jkernel.DownloadManager\n");
return;
}
jmethodID log = env->GetStaticMethodID(dm, "log", "(Ljava/lang/String;)V");
if (log == NULL) {
printf("Could not find method sun.jkernel.DownloadManager.log(String)\n");
return;
}
jstring string = env->NewStringUTF(msg);
if (string == NULL) {
printf("Error creating log string\n");
return;
}
env->CallStaticVoidMethod(dm, log, string);
}
}
void CDownloadDialog::logProgress() {
char msg[256];
sprintf(msg, "Progress: %d / %d", m_ulProgress, m_ulProgressMax);
log(msg);
}
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
//
// DownloadDialog.h : Declaration of the CDownloadDialog
//
#ifndef __DOWNLOADDIALOG_H_
#define __DOWNLOADDIALOG_H_
#include "resource.h" // main symbols
#include <time.h>
#include "jni.h"
#ifndef BUFFER_SIZE
#define BUFFER_SIZE 2048
#endif
#define iTimerID 1000
#define destroyWindowTimerID 2000
#define E_JDHELPER_TIMEOUT 12002
#define E_JDHELPER_NAME_NOT_RESOLVED 12007
#define E_JDHELPER_CANNOT_CONNECT 12029
/* Following lines were copied from the new version of commctrl.h
These definitions are not available in default version of
this header file in VS 2003 but they are needed to use
new Vista task dialog API.
*/
#ifndef TD_ERROR_ICON
/* These modifiers have sense with new VS only,
reset them to get code to compile */
#define __in
#define __in_opt
#define __out_opt
#ifdef _WIN32
#include <pshpack1.h>
#endif
typedef HRESULT (CALLBACK *PFTASKDIALOGCALLBACK)(HWND hwnd, __in UINT msg, __in WPARAM wParam, __in LPARAM lParam, __in LONG_PTR lpRefData);
enum _TASKDIALOG_FLAGS
{
TDF_ENABLE_HYPERLINKS = 0x0001,
TDF_USE_HICON_MAIN = 0x0002,
TDF_USE_HICON_FOOTER = 0x0004,
TDF_ALLOW_DIALOG_CANCELLATION = 0x0008,
TDF_USE_COMMAND_LINKS = 0x0010,
TDF_USE_COMMAND_LINKS_NO_ICON = 0x0020,
TDF_EXPAND_FOOTER_AREA = 0x0040,
TDF_EXPANDED_BY_DEFAULT = 0x0080,
TDF_VERIFICATION_FLAG_CHECKED = 0x0100,
TDF_SHOW_PROGRESS_BAR = 0x0200,
TDF_SHOW_MARQUEE_PROGRESS_BAR = 0x0400,
TDF_CALLBACK_TIMER = 0x0800,
TDF_POSITION_RELATIVE_TO_WINDOW = 0x1000,
TDF_RTL_LAYOUT = 0x2000,
TDF_NO_DEFAULT_RADIO_BUTTON = 0x4000,
TDF_CAN_BE_MINIMIZED = 0x8000
};
typedef int TASKDIALOG_FLAGS; // Note: _TASKDIALOG_FLAGS is an int
typedef enum _TASKDIALOG_MESSAGES
{
TDM_NAVIGATE_PAGE = WM_USER+101,
TDM_CLICK_BUTTON = WM_USER+102, // wParam = Button ID
TDM_SET_MARQUEE_PROGRESS_BAR = WM_USER+103, // wParam = 0 (nonMarque) wParam != 0 (Marquee)
TDM_SET_PROGRESS_BAR_STATE = WM_USER+104, // wParam = new progress state
TDM_SET_PROGRESS_BAR_RANGE = WM_USER+105, // lParam = MAKELPARAM(nMinRange, nMaxRange)
TDM_SET_PROGRESS_BAR_POS = WM_USER+106, // wParam = new position
TDM_SET_PROGRESS_BAR_MARQUEE = WM_USER+107, // wParam = 0 (stop marquee), wParam != 0 (start marquee), lparam = speed (milliseconds between repaints)
TDM_SET_ELEMENT_TEXT = WM_USER+108, // wParam = element (TASKDIALOG_ELEMENTS), lParam = new element text (LPCWSTR)
TDM_CLICK_RADIO_BUTTON = WM_USER+110, // wParam = Radio Button ID
TDM_ENABLE_BUTTON = WM_USER+111, // lParam = 0 (disable), lParam != 0 (enable), wParam = Button ID
TDM_ENABLE_RADIO_BUTTON = WM_USER+112, // lParam = 0 (disable), lParam != 0 (enable), wParam = Radio Button ID
TDM_CLICK_VERIFICATION = WM_USER+113, // wParam = 0 (unchecked), 1 (checked), lParam = 1 (set key focus)
TDM_UPDATE_ELEMENT_TEXT = WM_USER+114, // wParam = element (TASKDIALOG_ELEMENTS), lParam = new element text (LPCWSTR)
TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE = WM_USER+115, // wParam = Button ID, lParam = 0 (elevation not required), lParam != 0 (elevation required)
TDM_UPDATE_ICON = WM_USER+116 // wParam = icon element (TASKDIALOG_ICON_ELEMENTS), lParam = new icon (hIcon if TDF_USE_HICON_* was set, PCWSTR otherwise)
} TASKDIALOG_MESSAGES;
typedef enum _TASKDIALOG_NOTIFICATIONS
{
TDN_CREATED = 0,
TDN_NAVIGATED = 1,
TDN_BUTTON_CLICKED = 2, // wParam = Button ID
TDN_HYPERLINK_CLICKED = 3, // lParam = (LPCWSTR)pszHREF
TDN_TIMER = 4, // wParam = Milliseconds since dialog created or timer reset
TDN_DESTROYED = 5,
TDN_RADIO_BUTTON_CLICKED = 6, // wParam = Radio Button ID
TDN_DIALOG_CONSTRUCTED = 7,
TDN_VERIFICATION_CLICKED = 8, // wParam = 1 if checkbox checked, 0 if not, lParam is unused and always 0
TDN_HELP = 9,
TDN_EXPANDO_BUTTON_CLICKED = 10 // wParam = 0 (dialog is now collapsed), wParam != 0 (dialog is now expanded)
} TASKDIALOG_NOTIFICATIONS;
typedef struct _TASKDIALOG_BUTTON
{
int nButtonID;
PCWSTR pszButtonText;
} TASKDIALOG_BUTTON;
typedef enum _TASKDIALOG_ELEMENTS
{
TDE_CONTENT,
TDE_EXPANDED_INFORMATION,
TDE_FOOTER,
TDE_MAIN_INSTRUCTION
} TASKDIALOG_ELEMENTS;
typedef enum _TASKDIALOG_ICON_ELEMENTS
{
TDIE_ICON_MAIN,
TDIE_ICON_FOOTER
} TASKDIALOG_ICON_ELEMENTS;
#define TD_WARNING_ICON MAKEINTRESOURCEW(-1)
#define TD_ERROR_ICON MAKEINTRESOURCEW(-2)
#define TD_INFORMATION_ICON MAKEINTRESOURCEW(-3)
#define TD_SHIELD_ICON MAKEINTRESOURCEW(-4)
enum _TASKDIALOG_COMMON_BUTTON_FLAGS
{
TDCBF_OK_BUTTON = 0x0001, // selected control return value IDOK
TDCBF_YES_BUTTON = 0x0002, // selected control return value IDYES
TDCBF_NO_BUTTON = 0x0004, // selected control return value IDNO
TDCBF_CANCEL_BUTTON = 0x0008, // selected control return value IDCANCEL
TDCBF_RETRY_BUTTON = 0x0010, // selected control return value IDRETRY
TDCBF_CLOSE_BUTTON = 0x0020 // selected control return value IDCLOSE
};
typedef int TASKDIALOG_COMMON_BUTTON_FLAGS; // Note: _TASKDIALOG_COMMON_BUTTON_FLAGS is an int
typedef struct _TASKDIALOGCONFIG
{
UINT cbSize;
HWND hwndParent;
HINSTANCE hInstance; // used for MAKEINTRESOURCE() strings
TASKDIALOG_FLAGS dwFlags; // TASKDIALOG_FLAGS (TDF_XXX) flags
TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons; // TASKDIALOG_COMMON_BUTTON (TDCBF_XXX) flags
PCWSTR pszWindowTitle; // string or MAKEINTRESOURCE()
union
{
HICON hMainIcon;
PCWSTR pszMainIcon;
};
PCWSTR pszMainInstruction;
PCWSTR pszContent;
UINT cButtons;
const TASKDIALOG_BUTTON *pButtons;
int nDefaultButton;
UINT cRadioButtons;
const TASKDIALOG_BUTTON *pRadioButtons;
int nDefaultRadioButton;
PCWSTR pszVerificationText;
PCWSTR pszExpandedInformation;
PCWSTR pszExpandedControlText;
PCWSTR pszCollapsedControlText;
union
{
HICON hFooterIcon;
PCWSTR pszFooterIcon;
};
PCWSTR pszFooter;
PFTASKDIALOGCALLBACK pfCallback;
LONG_PTR lpCallbackData;
UINT cxWidth; // width of the Task Dialog's client area in DLU's. If 0, Task Dialog will calculate the ideal width.
} TASKDIALOGCONFIG;
WINCOMMCTRLAPI HRESULT WINAPI TaskDialogIndirect(const TASKDIALOGCONFIG *pTaskConfig, __out_opt int *pnButton, __out_opt int *pnRadioButton, __out_opt BOOL *pfVerificationFlagChecked);
WINCOMMCTRLAPI HRESULT WINAPI TaskDialog(__in_opt HWND hwndParent, __in_opt HINSTANCE hInstance, __in_opt PCWSTR pszWindowTitle, __in_opt PCWSTR pszMainInstruction, __in_opt PCWSTR pszContent, TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons, __in_opt PCWSTR pszIcon, __out_opt int *pnButton);
#ifdef _WIN32
#include <poppack.h>
#endif
#endif /* end of copy from commctrl.h */
typedef HRESULT (WINAPI *TaskDialogIndirectFn) (const TASKDIALOGCONFIG *pTaskConfig, __out_opt int *pnButton, __out_opt int *pnRadioButton, __out_opt BOOL *pfVerificationFlagChecked);
typedef enum {
DIALOG_ERROR_RETRYCANCEL = 0,
DIALOG_WARNING_CANCELOK
} DialogType;
/////////////////////////////////////////////////////////////////////////////
// CDownloadDialog
class CDownloadDialog :
public CAxDialogImpl<CDownloadDialog>
{
public:
CDownloadDialog();
~CDownloadDialog();
enum { IDD = IDD_DOWNLOAD_DIALOG };
BEGIN_MSG_MAP(CDownloadDialog)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
MESSAGE_HANDLER(WM_TIMER, OnTimer)
MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnCtlColorStatic)
COMMAND_ID_HANDLER(IDOK, OnOK)
COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
END_MSG_MAP()
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnOK(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
LRESULT OnCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnCtlColorStatic(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
STDMETHODIMP OnStartBinding();
STDMETHODIMP OnProgress(ULONG ulProgress);
void initDialogText(LPCTSTR pszDownloadURL, LPCTSTR pszBundleName);
BOOL isDownloading();
BOOL isDownloadCancelled();
void addToTotalContentLength(DWORD contentLength);
void decrementProgressMax(ULONG contentLength, ULONG readSoFar);
void bundleInstallStart();
void bundleInstallComplete();
void waitUntilInitialized();
void log(char *msg);
void logProgress();
void setFile(LPCTSTR pszFileName)
{
m_pszFileName = pszFileName;
}
void setURL(LPCTSTR pszURL)
{
m_pszURL = pszURL;
}
void setNameText(LPTSTR pszNameText)
{
m_pszNameText = pszNameText;
}
JNIEnv* getJNIEnv();
void setJavaVM(JavaVM *jvm)
{
m_jvm = jvm;
}
HRESULT DownloadConfiguration(LPTSTR pszConfigURL, LPTSTR pszConfigFile);
void delayedDoModal();
int SafeMessageBox(UINT details, UINT mainInstruction, UINT caption,
DialogType type, LPCWSTR instructionArg = NULL,
LPCWSTR detailsArg = NULL);
void destroyDialog();
private:
HFONT CreateDialogFont (HDC hdc, LPCTSTR lpszFaceName, int ptSize, int isBold = 0);
void FreeGDIResources ();
BOOL m_feedbackOnCancel;
TaskDialogIndirectFn taskDialogFn;
LPCTSTR m_pszFileName;
LPCTSTR m_pszURL;
time_t m_startTime;
ULONG m_ulProgress;
ULONG m_ulProgressMax;
int m_iProgressFactor;
int m_iMaxProgressFactor;
int m_numDownloadThreadsRunning;
BOOL m_destroyWindowTimerStarted;
volatile BOOL m_dialogUp;
CComAutoCriticalSection m_csDownload;
CComAutoCriticalSection m_csNumDownloadThreads;
HANDLE m_hCancelEvent;
HANDLE m_hDownloadThreadExitEvent;
HANDLE m_hDialogInitializedEvent;
HFONT m_hMastheadFont;
HFONT m_hDialogFont;
HFONT m_hSixPointFont;
LPTSTR m_pszNameText;
BITMAP m_bmMasthead;
HBITMAP m_hBitmap;
HDC m_hMemDC;
TCHAR m_szUrlPath[BUFFER_SIZE];
TCHAR m_szHostName[BUFFER_SIZE];
JavaVM* m_jvm;
CComAutoCriticalSection m_csMessageBox;
};
#endif //__DOWNLOADDIALOG_H_
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define STRICT
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif
#define _ATL_APARTMENT_THREADED
#include <atlbase.h>
//You may derive a class from CComModule and use it if you want to override
//something, but do not change the name of _Module
extern CComModule _Module;
#include <atlcom.h>
#include <atlwin.h>
#include <atlhost.h>
#include <commdlg.h>
#include <commctrl.h>
#include <windowsx.h>
#include <urlmon.h>
#include <wininet.h>
#include <shellapi.h>
#include <time.h>
#include <math.h>
#include <stdio.h>
#include <jni.h>
#include "resource.h" // main symbols
#include "DownloadHelper.h"
DownloadHelper::DownloadHelper() {
m_showProgressDialog = TRUE;
m_pszURL = NULL;
m_pszFileName = NULL;
m_pszNameText = NULL;
}
DownloadHelper::~DownloadHelper() {
}
HRESULT DownloadHelper::doDownload() {
return DownloadFile(m_pszURL, m_pszFileName, FALSE, m_showProgressDialog);
}
HRESULT DownloadHelper::DownloadFile(const TCHAR* szURL,
const TCHAR* szLocalFile, BOOL bResumable, BOOL bUIFeedback) {
HINTERNET hOpen = NULL;
HINTERNET hConnect = NULL;
HINTERNET hRequest = NULL;
HANDLE hFile = INVALID_HANDLE_VALUE;
DWORD dwDownloadError = 0;
DWORD nContentLength = 0;
/* Some of error messages use drive letter.
Result is something like "(C:)".
NB: Parentheses are added here because in some other places
we same message but can not provide disk label info */
TCHAR drivePath[5];
/* assuming szLocalFile is not NULL */
_sntprintf(drivePath, 5, "(%c:)", szLocalFile[0]);
WCHAR* wName = CT2CW(drivePath);
__try {
m_csDownload.Lock();
time(&m_startTime);
}
__finally {
m_csDownload.Unlock();
}
__try {
// block potential security hole
if (strstr(szURL, TEXT("file://")) != NULL) {
dwDownloadError = 1;
__leave;
}
HWND hProgressInfo = NULL;
TCHAR szStatus[BUFFER_SIZE];
if (bUIFeedback) {
// init download dialg text
m_dlg->initDialogText(m_pszURL, m_pszNameText);
}
// Open Internet Call
hOpen = ::InternetOpen("deployHelper", INTERNET_OPEN_TYPE_PRECONFIG,
NULL, NULL, NULL);
if (hOpen == NULL) {
dwDownloadError = 1;
__leave;
}
// URL components
URL_COMPONENTS url_components;
::ZeroMemory(&url_components, sizeof(URL_COMPONENTS));
TCHAR szHostName[BUFFER_SIZE], szUrlPath[BUFFER_SIZE],
szExtraInfo[BUFFER_SIZE];
url_components.dwStructSize = sizeof(URL_COMPONENTS);
url_components.lpszHostName = szHostName;
url_components.dwHostNameLength = BUFFER_SIZE;
url_components.nPort = NULL;
url_components.lpszUrlPath = szUrlPath;
url_components.dwUrlPathLength = BUFFER_SIZE;
url_components.lpszExtraInfo = szExtraInfo;
url_components.dwExtraInfoLength = BUFFER_SIZE;
// Crack the URL into pieces
::InternetCrackUrl(szURL, lstrlen(szURL), NULL, &url_components);
// Open Internet Connection
hConnect = ::InternetConnect(hOpen, url_components.lpszHostName,
url_components.nPort, "", "", INTERNET_SERVICE_HTTP, NULL,
NULL);
if (hConnect == NULL) {
dwDownloadError = 1;
__leave;
}
// Determine the relative URL path by combining
// Path and ExtraInfo
char szURL[4096];
if (url_components.dwUrlPathLength != 0)
lstrcpy(szURL, url_components.lpszUrlPath);
else
lstrcpy(szURL, "/");
if (url_components.dwExtraInfoLength != 0)
lstrcat(szURL, url_components.lpszExtraInfo);
BOOL bRetryHttpRequest = FALSE;
int numberOfRetry = 0;
long secondsToWait = 60;
do {
bRetryHttpRequest = FALSE;
// Make a HTTP GET request
hRequest = ::HttpOpenRequest(hConnect, "GET", szURL, "HTTP/1.1",
"", NULL,
INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_DONT_CACHE,
0);
if (hRequest == NULL) {
dwDownloadError = 1;
__leave;
}
// Create or open existing destination file
hFile = ::CreateFile(szLocalFile, GENERIC_WRITE, 0, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
if (bUIFeedback) {
if (IDRETRY == m_dlg->SafeMessageBox(
IDS_DISK_WRITE_ERROR,
IDS_DISK_WRITE_ERROR_CAPTION,
IDS_ERROR_CAPTION,
DIALOG_ERROR_RETRYCANCEL,
wName)) {
bRetryHttpRequest = TRUE;
continue;
}
}
dwDownloadError = 1;
__leave;
}
DWORD fileSize = GetFileSize(hFile, NULL);
// Check if resumable download is enabled
if (bResumable == FALSE) {
// Start from scratch
fileSize = 0;
}
FILETIME tWrite;
BOOL rangereq = FALSE;
if ((fileSize != 0) && (fileSize != 0xFFFFFFFF) &&
GetFileTime(hFile, NULL, NULL, &tWrite)) {
char szHead[100];
SYSTEMTIME tLocal;
char buf[INTERNET_RFC1123_BUFSIZE];
FileTimeToSystemTime(&tWrite, &tLocal);
InternetTimeFromSystemTime(&tLocal, INTERNET_RFC1123_FORMAT,
buf, INTERNET_RFC1123_BUFSIZE);
sprintf(szHead, "Range: bytes=%d-\r\nIf-Range: %s\r\n",
fileSize, buf);
HttpAddRequestHeaders(hRequest, szHead, lstrlen(szHead),
HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE);
rangereq = TRUE;
}
// This is a loop to handle various potential error when the
// connection is made
BOOL bCont = TRUE;
while ((FALSE == ::HttpSendRequest(hRequest, NULL, NULL, NULL, NULL))
&& bCont ) {
// We might have an invalid CA.
DWORD dwErrorCode = GetLastError();
switch(dwErrorCode) {
case E_JDHELPER_TIMEOUT:
case E_JDHELPER_NAME_NOT_RESOLVED:
case E_JDHELPER_CANNOT_CONNECT: {
bCont = FALSE;
// Display the information dialog
if (bUIFeedback) {
// decrement download counter to prevent progress
// dialog from popping up while the message box is
// up
m_dlg->bundleInstallComplete();
if (dwErrorCode == E_JDHELPER_TIMEOUT) {
bRetryHttpRequest =
(IDRETRY == m_dlg->SafeMessageBox(
IDS_HTTP_STATUS_REQUEST_TIMEOUT,
IDS_HTTP_INSTRUCTION_REQUEST_TIMEOUT,
IDS_ERROR_CAPTION,
DIALOG_ERROR_RETRYCANCEL));
} else {
bRetryHttpRequest =
(IDRETRY == m_dlg->SafeMessageBox(
IDS_HTTP_STATUS_SERVER_NOT_REACHABLE,
IDS_HTTP_INSTRUCTION_SERVER_NOT_REACHABLE,
IDS_ERROR_CAPTION,
DIALOG_ERROR_RETRYCANCEL));
}
// re-increment counter because it will be decremented
// again upon return
m_dlg->bundleInstallStart();
bCont = bRetryHttpRequest;
}
break;
}
case ERROR_INTERNET_INVALID_CA:
case ERROR_INTERNET_SEC_CERT_CN_INVALID:
case ERROR_INTERNET_SEC_CERT_DATE_INVALID:
case ERROR_INTERNET_HTTP_TO_HTTPS_ON_REDIR:
case ERROR_INTERNET_INCORRECT_PASSWORD:
case ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED:
default: {
// Unless the user agrees to continue, we just
// abandon now !
bCont = FALSE;
// Make sure to test the return code from
// InternetErrorDlg user may click OK or Cancel. In
// case of Cancel, request should not be resubmitted
if (bUIFeedback) {
if (ERROR_SUCCESS == ::InternetErrorDlg(
NULL, hRequest,
dwErrorCode,
FLAGS_ERROR_UI_FILTER_FOR_ERRORS |
FLAGS_ERROR_UI_FLAGS_GENERATE_DATA |
FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS,
NULL))
bCont = TRUE;
}
}
}
}
if (bCont == FALSE) {
// User has denied the request
dwDownloadError = 1;
__leave;
}
//
// Read HTTP status code
//
DWORD dwErrorCode = GetLastError();
DWORD dwStatus=0;
DWORD dwStatusSize = sizeof(DWORD);
if (FALSE == ::HttpQueryInfo(hRequest, HTTP_QUERY_FLAG_NUMBER |
HTTP_QUERY_STATUS_CODE, &dwStatus, &dwStatusSize, NULL)) {
dwErrorCode = GetLastError();
}
bCont = TRUE;
while ((dwStatus == HTTP_STATUS_PROXY_AUTH_REQ ||
dwStatus == HTTP_STATUS_DENIED) &&
bCont) {
int result = ::InternetErrorDlg(GetDesktopWindow(), hRequest, ERROR_INTERNET_INCORRECT_PASSWORD,
FLAGS_ERROR_UI_FILTER_FOR_ERRORS |
FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS |
FLAGS_ERROR_UI_FLAGS_GENERATE_DATA,
NULL);
if (ERROR_CANCELLED == result) {
bCont = FALSE;
}
else {
::HttpSendRequest(hRequest, NULL, 0, NULL, 0);
// Reset buffer length
dwStatusSize = sizeof(DWORD);
::HttpQueryInfo(hRequest, HTTP_QUERY_FLAG_NUMBER |
HTTP_QUERY_STATUS_CODE, &dwStatus, &dwStatusSize,
NULL);
}
}
if (dwStatus == HTTP_STATUS_OK ||
dwStatus == HTTP_STATUS_PARTIAL_CONTENT) {
// Determine content length, so we may show the progress bar
// meaningfully
//
nContentLength = 0;
DWORD nLengthSize = sizeof(DWORD);
::HttpQueryInfo(hRequest,
HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER,
&nContentLength, &nLengthSize, NULL);
if (nContentLength <= 0) {
// If can't estimate content length, estimate it
// to be 6MB
nContentLength = 15000000;
}
else if (rangereq && (fileSize != 0) &&
(nContentLength == fileSize)) {
// If the file is already downloaded completely and then
// we send a range request, the whole file is sent instead
// of nothing. So avoid downloading again.
// Some times return value is 206, even when whole file
// is sent. So check if "Content-range:" is present in the
// reply
char buffer[256];
DWORD length = sizeof(buffer);
if(!HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_RANGE,
buffer, &length, NULL)) {
if(HttpQueryInfo(hRequest, HTTP_QUERY_LAST_MODIFIED,
buffer, &length, NULL)) {
SYSTEMTIME systime;
FILETIME filtime;
InternetTimeToSystemTime(buffer, &systime, NULL);
SystemTimeToFileTime(&systime, &filtime);
if ((CompareFileTime(&tWrite, &filtime)) == 1) {
// no need to download
dwDownloadError = 0;
__leave;
}
}
else {
::SetFilePointer(hFile, 0, 0, FILE_BEGIN);
::SetEndOfFile(hFile); // truncate the file
}
}
}
TCHAR szBuffer[8096];
DWORD dwBufferSize = 8096;
// Read from HTTP connection and write into
// destination file
//
DWORD nRead = 0;
DWORD dwTotalRead = 0;
BOOL bCancel = FALSE;
if (dwStatus == HTTP_STATUS_PARTIAL_CONTENT) {
// If we are using resumable download, fake
// start time so it looks like we have begun
// the download several minutes again.
//
m_startTime = m_startTime - 100;
::SetFilePointer(hFile, 0, 0, FILE_END); // seek to end
}
else {
::SetFilePointer(hFile, 0, 0, FILE_BEGIN);
::SetEndOfFile(hFile); // truncate the file
}
do {
nRead=0;
if (::InternetReadFile(hRequest, szBuffer, dwBufferSize,
&nRead)) {
if (nRead) {
DWORD dwNumberOfBytesWritten = NULL;
BOOL ret = WriteFile(hFile, szBuffer, nRead,
&dwNumberOfBytesWritten, NULL);
if (!ret) {
// WriteFile failed
if (bUIFeedback) {
if (GetLastError() == ERROR_DISK_FULL) {
bRetryHttpRequest =
(IDRETRY == m_dlg->SafeMessageBox(
IDS_DISK_FULL_ERROR,
IDS_DISK_FULL_ERROR_CAPTION,
IDS_ERROR_CAPTION,
DIALOG_ERROR_RETRYCANCEL,
wName));
} else {
bRetryHttpRequest =
(IDRETRY == m_dlg->SafeMessageBox(
IDS_DISK_WRITE_ERROR,
IDS_DISK_WRITE_ERROR_CAPTION,
IDS_ERROR_CAPTION,
DIALOG_ERROR_RETRYCANCEL,
wName));
}
if (!bRetryHttpRequest) {
dwDownloadError = 1;
break;
}
}
continue;
}
}
dwTotalRead += nRead;
// update download progress dialog
m_dlg->OnProgress(nRead);
// Check if download has been cancelled
if (m_dlg->isDownloadCancelled()) {
m_dlg->decrementProgressMax(nContentLength,
dwTotalRead);
bCancel = TRUE;
break;
}
}
else {
bCancel = TRUE;
break;
}
}
while (nRead);
if (bCancel) {
// User has cancelled the operation or InternetRead failed
// don't do return here, we need to cleanup
dwDownloadError = 1;
__leave;
}
}
else if (dwStatus == 416 && (fileSize != 0) &&
(fileSize != 0xFFFFFFFF)) {
// This error could be returned, When the full file exists
// and a range request is sent with range beyond filessize.
// The best way to fix this is in future is, to send HEAD
// request and get filelength before sending range request.
dwDownloadError = 0;
__leave;
}
else if (dwStatus == 403) { // Forbidden from Akamai means we need to get a new download token
JNIEnv *env = m_dlg->getJNIEnv();
jclass exceptionClass = env->FindClass("java/net/HttpRetryException");
if (exceptionClass == NULL) {
/* Unable to find the exception class, give up. */
__leave;
}
jmethodID constructor;
constructor = env->GetMethodID(exceptionClass,
"<init>", "(Ljava/lang/String;I)V");
if (constructor != NULL) {
jobject exception = env->NewObject(exceptionClass,
constructor, env->NewStringUTF("Forbidden"),
403);
env->Throw((jthrowable) exception);
}
__leave;
}
else if(dwStatus >= 400 && dwStatus < 600) {
/* NB: Following case seems to be never used!
HTTP_STATUS_FORBIDDEN is the same as 403 and
403 was specially handled few lines above! */
if (dwStatus == HTTP_STATUS_FORBIDDEN) {
if (bUIFeedback) {
bRetryHttpRequest = (IDRETRY == m_dlg->SafeMessageBox(
IDS_HTTP_STATUS_FORBIDDEN,
IDS_HTTP_INSTRUCTION_FORBIDDEN,
IDS_ERROR_CAPTION,
DIALOG_ERROR_RETRYCANCEL,
L"403"));
}
}
else if (dwStatus == HTTP_STATUS_SERVER_ERROR) {
if (bUIFeedback) {
bRetryHttpRequest = (IDRETRY == m_dlg->SafeMessageBox(
IDS_HTTP_STATUS_SERVER_ERROR,
IDS_HTTP_INSTRUCTION_UNKNOWN_ERROR,
IDS_ERROR_CAPTION,
DIALOG_ERROR_RETRYCANCEL,
L"500"));
}
}
else if (dwStatus == HTTP_STATUS_SERVICE_UNAVAIL) {
if (numberOfRetry < 5) {
// If the server is busy, automatically retry
// We wait couple seconds before retry to avoid
// congestion
for (long i = (long) secondsToWait; i >= 0; i--) {
// Update status
if (bUIFeedback) {
char szBuffer[BUFFER_SIZE];
::LoadString(_Module.GetResourceInstance(),
IDS_DOWNLOAD_STATUS_RETRY, szStatus,
BUFFER_SIZE);
wsprintf(szBuffer, szStatus, i);
::SetWindowText(hProgressInfo, szBuffer);
}
// Sleep 1 second
::Sleep(1000);
}
// We use a semi-binary backoff algorithm to
// determine seconds to wait
numberOfRetry += 1;
secondsToWait = secondsToWait + 30;
bRetryHttpRequest = TRUE;
continue;
}
else {
if (bUIFeedback) {
bRetryHttpRequest = (IDRETRY == m_dlg->SafeMessageBox(
IDS_HTTP_STATUS_SERVICE_UNAVAIL,
IDS_HTTP_INSTRUCTION_SERVICE_UNAVAIL,
IDS_ERROR_CAPTION,
DIALOG_ERROR_RETRYCANCEL,
L"503"));
if (bRetryHttpRequest) {
numberOfRetry = 0;
secondsToWait = 60;
continue;
}
}
}
}
else {
if (bUIFeedback) {
WCHAR szBuffer[10];
_snwprintf(szBuffer, 10, L"%d", dwStatus);
bRetryHttpRequest = (IDRETRY == m_dlg->SafeMessageBox(
IDS_HTTP_STATUS_OTHER,
IDS_HTTP_INSTRUCTION_UNKNOWN_ERROR,
IDS_ERROR_CAPTION,
DIALOG_ERROR_RETRYCANCEL,
szBuffer));
}
}
if (!bRetryHttpRequest) {
dwDownloadError = 1;
}
}
else {
if (bUIFeedback) {
WCHAR szBuffer[10];
_snwprintf(szBuffer, 10, L"%d", dwStatus);
bRetryHttpRequest = (IDRETRY == m_dlg->SafeMessageBox(
IDS_HTTP_STATUS_OTHER,
IDS_HTTP_INSTRUCTION_UNKNOWN_ERROR,
IDS_ERROR_CAPTION,
DIALOG_ERROR_RETRYCANCEL,
szBuffer));
}
if (!bRetryHttpRequest) {
dwDownloadError = 1;
}
}
// Close HTTP request
//
// This is necessary if the HTTP request
// is retried
if (hRequest)
::InternetCloseHandle(hRequest);
if (hFile != INVALID_HANDLE_VALUE) {
::CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
}
}
while (bRetryHttpRequest);
}
__finally {
if (hRequest)
::InternetCloseHandle(hRequest);
if (hConnect)
::InternetCloseHandle(hConnect);
if (hOpen)
::InternetCloseHandle(hOpen);
if (hFile != INVALID_HANDLE_VALUE)
::CloseHandle(hFile);
}
// Exit dialog
if (dwDownloadError == 0) {
return S_OK;
} else {
DeleteFile(szLocalFile);
return E_FAIL;
}
}
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
#ifndef BUFFER_SIZE
#define BUFFER_SIZE 2048
#endif
#define E_JDHELPER_TIMEOUT 12002
#define E_JDHELPER_NAME_NOT_RESOLVED 12007
#define E_JDHELPER_CANNOT_CONNECT 12029
#include <jni.h>
#include "DownloadDialog.h"
class DownloadHelper {
public:
DownloadHelper();
~DownloadHelper();
HRESULT doDownload();
void setFile(LPCTSTR pszFileName) {
m_pszFileName = pszFileName;
}
void setURL(LPCTSTR pszURL) {
m_pszURL = pszURL;
}
void setNameText(LPTSTR pszNameText) {
m_pszNameText = pszNameText;
}
void setShowProgressDialog(BOOL showProgress) {
m_showProgressDialog = showProgress;
}
void setDownloadDialog(CDownloadDialog* dialog) {
m_dlg = dialog;
}
void setJavaVM(JavaVM *jvm) {
m_jvm = jvm;
}
private:
HRESULT DownloadFile(const TCHAR* szURL, const TCHAR* szLocalFile,
BOOL bResumable, BOOL bUIFeedback);
BOOL m_showProgressDialog;
LPCTSTR m_pszURL;
LPCTSTR m_pszFileName;
LPTSTR m_pszNameText;
time_t m_startTime;
CComAutoCriticalSection m_csDownload;
CDownloadDialog* m_dlg;
JavaVM* m_jvm;
};
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
#define _WIN32_WINNT 0x0500
#define WINVER 0x0500
#include "stdafx.h"
#include <shlobj.h>
#include <atlbase.h>
#include <locale.h>
CComModule _Module;
#include <atlwin.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "Windows.h"
#include "WinNT.h"
#include <shellapi.h>
#include "DownloadDialog.h"
#include "DownloadHelper.h"
#include "kernel.h"
#include "sun_jkernel_DownloadManager.h"
#include "sun_jkernel_Bundle.h"
#include "sun_jkernel_Mutex.h"
#include "sun_jkernel_BackgroundDownloader.h"
#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <tchar.h>
#include <tchar.h>
#include <sddl.h>
#include <Aclapi.h>
#include <strsafe.h>
BOOL IsPlatformWindowsVista();
#define BUFSIZE 4096
#define JBROKERPIPE "\\\\.\\pipe\\jbrokerpipe"
#define JREMAINKEY "SOFTWARE\\JavaSoft\\Java Runtime Environment"
#define JRE_VERSION_REGISTRY_KEY JREMAINKEY "\\" VERSION
#define ReleaseAndClose(mutex) \
if (mutex != NULL) { \
ReleaseMutex(mutex); \
CloseHandle(mutex); \
mutex = NULL; \
}
#define KERNEL_DEBUG false
// used to inform kernel that we believe it is running in high integrity
#define JBROKER_KEY "-Dkernel.spawned.from.jbroker=true -Dkernel.background.download=false"
// this is only available on Vista SDK, hard code it here for now
#define LABEL_SECURITY_INFORMATION (0x00000010L)
// The LABEL_SECURITY_INFORMATION SDDL SACL to be set for low integrity
LPCSTR LOW_INTEGRITY_SDDL_SACL = "S:(ML;;NW;;;LW)";
CDownloadDialog dlg;
BOOL createDialog = TRUE;
CComAutoCriticalSection m_csCreateDialog;
typedef BOOL (WINAPI *LPFNInitializeSecurityDescriptor)(
PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD dwRevision);
typedef BOOL (WINAPI *LPFNSetSecurityDescriptorDacl)(
PSECURITY_DESCRIPTOR pSecurityDescriptor, BOOL bDaclPresent, PACL pDacl,
BOOL bDaclDefaulted);
typedef BOOL (WINAPI *LPFNConvertStringSecurityDescriptorToSecurityDescriptorA)(
LPCSTR StringSecurityDescriptor, DWORD StringSDRevision,
PSECURITY_DESCRIPTOR* SecurityDescriptor,
PULONG SecurityDescriptorSize);
typedef BOOL (WINAPI *LPFNGetSecurityDescriptorSacl)(
PSECURITY_DESCRIPTOR pSecurityDescriptor, LPBOOL lpbSaclPresent,
PACL* pSacl, LPBOOL lpbSaclDefaulted);
typedef DWORD (WINAPI *LPFNSetSecurityInfo)(HANDLE handle,
SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl);
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
char* getStringPlatformChars(JNIEnv* env, jstring jstr) {
char *result = NULL;
size_t len;
const jchar* utf16 = env->GetStringChars(jstr, NULL);
len = wcstombs(NULL, utf16, env->GetStringLength(jstr) * 4) + 1;
if (len == -1)
return NULL;
result = (char*) malloc(len);
if (wcstombs(result, utf16, len) == -1)
return NULL;
env->ReleaseStringChars(jstr, utf16);
return result;
}
bool SetObjectToLowIntegrity ( HANDLE hObject,
SE_OBJECT_TYPE type = SE_KERNEL_OBJECT ) {
bool bRet = false;
DWORD dwErr = ERROR_SUCCESS;
PSECURITY_DESCRIPTOR pSD = NULL;
PACL pSacl = NULL;
BOOL fSaclPresent = FALSE;
BOOL fSaclDefaulted = FALSE;
// initialize function pointers
HMODULE hModule = LoadLibrary("Advapi32.dll");
// ConvertStringSecurityDescriptorToSecurityDescriptorA
LPFNConvertStringSecurityDescriptorToSecurityDescriptorA
lpfnConvertStringSecurityDescriptorToSecurityDescriptorA =
(LPFNConvertStringSecurityDescriptorToSecurityDescriptorA)GetProcAddress(
hModule,
"ConvertStringSecurityDescriptorToSecurityDescriptorA");
// GetSecurityDescriptorSacl
LPFNGetSecurityDescriptorSacl lpfnGetSecurityDescriptorSacl =
(LPFNGetSecurityDescriptorSacl)GetProcAddress(hModule,
"GetSecurityDescriptorSacl");
// SetSecurityInfo
LPFNSetSecurityInfo lpfnSetSecurityInfo =
(LPFNSetSecurityInfo)GetProcAddress(hModule,
"SetSecurityInfo");
if (lpfnConvertStringSecurityDescriptorToSecurityDescriptorA == NULL ||
lpfnGetSecurityDescriptorSacl == NULL ||
lpfnSetSecurityInfo == NULL) {
if (KERNEL_DEBUG) {
printf("Fail to initialize function pointer\n");
}
FreeLibrary(hModule);
return FALSE;
}
// Set object to lower integrity
if ( lpfnConvertStringSecurityDescriptorToSecurityDescriptorA(
LOW_INTEGRITY_SDDL_SACL, SDDL_REVISION_1, &pSD, NULL ) ) {
if ( lpfnGetSecurityDescriptorSacl(
pSD, &fSaclPresent, &pSacl, &fSaclDefaulted ) ) {
dwErr = lpfnSetSecurityInfo(
hObject, type, LABEL_SECURITY_INFORMATION,
NULL, NULL, NULL, pSacl );
bRet = (ERROR_SUCCESS == dwErr);
}
LocalFree( pSD );
}
FreeLibrary(hModule);
return bRet;
}
JNIEXPORT jlong JNICALL Java_sun_jkernel_Mutex_createNativeMutex
(JNIEnv *env , jclass cls, jstring id) {
SECURITY_ATTRIBUTES sa;
PSECURITY_DESCRIPTOR pSD = NULL;
BOOL saInitialized = FALSE;
// initialize function pointers
HMODULE hModule = LoadLibrary("Advapi32.dll");
// InitializeSecurityDescriptor
LPFNInitializeSecurityDescriptor lpfnInitializeSecurityDescriptor =
(LPFNInitializeSecurityDescriptor)GetProcAddress(hModule,
"InitializeSecurityDescriptor");
// SetSecurityDescriptorDacl
LPFNSetSecurityDescriptorDacl lpfnSetSecurityDescriptorDacl =
(LPFNSetSecurityDescriptorDacl)GetProcAddress(hModule,
"SetSecurityDescriptorDacl");
if (lpfnInitializeSecurityDescriptor != NULL &&
lpfnSetSecurityDescriptorDacl != NULL) {
// Initialize a security descriptor.
pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,
SECURITY_DESCRIPTOR_MIN_LENGTH);
if (NULL == pSD) {
if (KERNEL_DEBUG) {
printf("LocalAlloc Error %u\n", GetLastError());
}
FreeLibrary(hModule);
return NULL;
}
if (!lpfnInitializeSecurityDescriptor(pSD,
SECURITY_DESCRIPTOR_REVISION)) {
if (KERNEL_DEBUG) {
printf("InitializeSecurityDescriptor Error %u\n", GetLastError());
}
FreeLibrary(hModule);
return NULL;
}
// Add the ACL to the security descriptor.
if (!lpfnSetSecurityDescriptorDacl(pSD,
TRUE, // bDaclPresent flag
NULL, // NULL DACL is assigned to the security descriptor,
// which allows all access to the object.
// This is to allow the mutex to be accessbile by
// all users; The background downloader launched
// by the installer will be running as SYSTEM user;
// while other java process started by the current
// user will be running as the current username.
FALSE)) // not a default DACL
{
if (KERNEL_DEBUG) {
printf("SetSecurityDescriptorDacl Error %u\n",
GetLastError());
}
FreeLibrary(hModule);
return NULL;
}
// Initialize a security attributes structure.
sa.nLength = sizeof (SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = pSD;
sa.bInheritHandle = FALSE;
saInitialized = TRUE;
FreeLibrary(hModule);
}
HANDLE m = CreateMutex(saInitialized ? &sa : NULL, FALSE,
(LPCSTR) getStringPlatformChars(env, id));
if (m == NULL) {
if (KERNEL_DEBUG) {
printf("CreateMutex Error %u\n", GetLastError());
}
}
// set the mutex object to low integrity on vista, so the mutex
// can be accessed by different integrity level
if (IsPlatformWindowsVista()) {
if (!SetObjectToLowIntegrity(m)) {
if (KERNEL_DEBUG) {
printf("Fail to set Mutex object to low integrity\n");
}
}
}
return (jlong)m ;
}
HANDLE getMutexHandle(JNIEnv *env, jobject mutex) {
jfieldID handle = env->GetFieldID(env->GetObjectClass(mutex), "handle", "J");
return (HANDLE) env->GetLongField(mutex, handle);
}
JNIEXPORT jboolean JNICALL Java_sun_jkernel_Mutex_acquire__I
(JNIEnv *env, jobject mutex, jint timeout) {
HANDLE hmutex = getMutexHandle(env, mutex);
if (hmutex != NULL) {
int result = WaitForSingleObject(hmutex, timeout);
if (result == WAIT_ABANDONED)
result = WaitForSingleObject(hmutex, timeout);
return (result == WAIT_OBJECT_0);
}
else
return false;
}
void ThrowByName(JNIEnv *env, const char *name, const char *msg) {
jclass cls = env->FindClass(name);
/* if cls is NULL, an exception has already been thrown */
if (cls != NULL) {
env->ThrowNew(cls, msg);
}
/* free the local ref */
env->DeleteLocalRef(cls);
}
JNIEXPORT void JNICALL Java_sun_jkernel_Mutex_acquire__
(JNIEnv *env, jobject mutex) {
if (!Java_sun_jkernel_Mutex_acquire__I(env, mutex, INFINITE)) {
// failed to acquire mutex, most likely because it was already disposed
ThrowByName(env, "java/lang/IllegalStateException",
"error acquiring mutex");
}
}
JNIEXPORT void JNICALL Java_sun_jkernel_Mutex_release
(JNIEnv *env, jobject mutex) {
HANDLE hmutex = getMutexHandle(env, mutex);
if (hmutex != NULL)
ReleaseMutex(hmutex);
else
ThrowByName(env, "java/lang/IllegalStateException",
"releasing disposed mutex");
}
JNIEXPORT void JNICALL Java_sun_jkernel_Mutex_destroyNativeMutex
(JNIEnv *env, jobject mutex) {
HANDLE hmutex = getMutexHandle(env, mutex);
if (hmutex != NULL) {
Java_sun_jkernel_Mutex_release(env, mutex);
CloseHandle(hmutex);
}
}
void createDownloadWindowProc(LPVOID lpParameter) {
CDownloadDialog* pDlg = (CDownloadDialog *) lpParameter;
pDlg->delayedDoModal();
// dialog destroyed, need to create a new one next time
createDialog = TRUE;
}
void createDownloadWindow(LPVOID lpParameter) {
// Create a new thread for download window
DWORD dwThreadId = NULL;
::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) createDownloadWindowProc, lpParameter, 0, &dwThreadId);
}
JNIEXPORT void JNICALL Java_sun_jkernel_DownloadManager_bundleInstallComplete
(JNIEnv *env, jclass dm) {
dlg.bundleInstallComplete();
}
JNIEXPORT void JNICALL Java_sun_jkernel_DownloadManager_bundleInstallStart
(JNIEnv *env, jclass dm) {
dlg.bundleInstallStart();
}
typedef HRESULT (WINAPI *LPFNIEIsProtectedModeProcess)(BOOL *pbResult);
BOOL isRunningIEProtectedMode() {
HMODULE hModule = NULL;
LPFNIEIsProtectedModeProcess lpfnIEIsProtectedModeProcess;
__try {
hModule = LoadLibrary("ieframe.dll");
if (hModule != NULL) {
lpfnIEIsProtectedModeProcess = (LPFNIEIsProtectedModeProcess)
GetProcAddress(hModule, "IEIsProtectedModeProcess");
if (lpfnIEIsProtectedModeProcess != NULL) {
BOOL bProtectedMode = FALSE;
HRESULT hr = lpfnIEIsProtectedModeProcess(&bProtectedMode);
if ( SUCCEEDED(hr) && bProtectedMode ) {
// IE is running in protected mode
return TRUE;
} else {
// IE isn't running in protected mode
return FALSE;
}
}
}
} __finally {
if (hModule != NULL) {
FreeLibrary(hModule);
}
}
return FALSE;
}
/* Return TRUE if current running platform is Windows Vista, FALSE otherwise */
BOOL IsPlatformWindowsVista() {
static BOOL initialized = FALSE;
static BOOL isVista = FALSE;
OSVERSIONINFO osvi;
if (initialized) {
return isVista;
}
// Initialize the OSVERSIONINFO structure.
ZeroMemory( &osvi, sizeof( osvi ) );
osvi.dwOSVersionInfoSize = sizeof( osvi );
GetVersionEx( &osvi ); // Assume this function succeeds.
if ( osvi.dwPlatformId == VER_PLATFORM_WIN32_NT &&
osvi.dwMajorVersion == 6 ) {
isVista = TRUE;
} else {
isVista = FALSE;
}
initialized = TRUE;
return isVista;
}
JNIEXPORT jboolean JNICALL Java_sun_jkernel_DownloadManager_isIEProtectedMode
(JNIEnv *env, jclass dm) {
if (isRunningIEProtectedMode()) {
return TRUE;
}
return FALSE;
}
JNIEXPORT jboolean JNICALL Java_sun_jkernel_DownloadManager_isWindowsVista
(JNIEnv *env, jclass dm) {
if (IsPlatformWindowsVista()) {
return TRUE;
}
return FALSE;
}
int sendMessageToBroker(const char * message) {
char ackString[1024];
HANDLE hp = INVALID_HANDLE_VALUE;
while (hp == INVALID_HANDLE_VALUE) {
hp = CreateNamedPipe(_T(JBROKERPIPE),
PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE ,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
1, // number of pipes that can exist
1024, // output buffer
1024, // input buffer
0, // timeout
NULL); // security attributes
if (hp == INVALID_HANDLE_VALUE) {
DWORD err = GetLastError();
// we only allow one instance of the pipe; if the instance
// already exists, we will get ERROR_ACCESS_DENIED, which means
// some other process is using the pipe, so let's try again
if (err != ERROR_ACCESS_DENIED && err != ERROR_PIPE_BUSY) {
// create pipe failed
return 0;
}
// pipe instance might be in use, keep trying
}
}
// Wait for the client to connect; if it succeeds,
// the function returns a nonzero value. If the function
// returns zero, GetLastError returns ERROR_PIPE_CONNECTED.
BOOL fConnected = ConnectNamedPipe(hp, NULL) ?
TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
if (fConnected)
{
// Send message to the pipe server.
DWORD cbWritten;
BOOL fSuccess = WriteFile(
hp, // pipe handle
message, // message
(strlen(message)+1)*sizeof(char), // message length
&cbWritten, // bytes written
NULL); // not overlapped
if (!fSuccess)
{
// WriteFile failed
CloseHandle(hp);
return 0;
}
// wait for ack from server
DWORD cbRead;
TCHAR chBuf[BUFSIZE];
do
{
// Read from the pipe.
fSuccess = ReadFile(
hp, // pipe handle
chBuf, // buffer to receive reply
BUFSIZE*sizeof(TCHAR), // size of buffer
&cbRead, // number of bytes read
NULL); // not overlapped
if (! fSuccess && GetLastError() != ERROR_MORE_DATA)
break;
sprintf(ackString, "%s", chBuf);
} while (!fSuccess); // repeat loop if ERROR_MORE_DATA
}
CloseHandle(hp);
if (strcmp(ackString, "SUCCESS") == 0) {
// server completed move command successfully
return 1;
}
return 0;
}
int sendMoveMessageToBroker(const char * fromPath, const char * userHome) {
// Send move message
char * movecmd = "MOVEFILE";
char * msg = (char*)malloc((strlen(fromPath) + strlen(movecmd) +
strlen(userHome) + 3) * sizeof(char));
sprintf(msg, "%s*%s*%s", movecmd, fromPath, userHome);
return sendMessageToBroker(msg);
}
int sendMoveDirMessageToBroker(const char * fromPath, const char * userHome) {
// Send move dir message
char * movecmd = "MOVEDIR";
char * msg = (char*)malloc((strlen(fromPath) + strlen(movecmd) +
strlen(userHome) + 3) * sizeof(char));
sprintf(msg, "%s*%s*%s", movecmd, fromPath, userHome);
return sendMessageToBroker(msg);
}
int sendKillMessageToBroker() {
// Send move message
char * killcmd = "KILLBROKER";
return sendMessageToBroker(killcmd);
}
int sendPerformCompletionMessageToBroker(const char *javaHome) {
const char *cmd = "PERFORMCOMPLETION";
int result = sendMessageToBroker(cmd);
if (result)
sendKillMessageToBroker();
return result;
}
int getConstantInt(JNIEnv *env, jclass cls, const char *name) {
jfieldID handle = env->GetStaticFieldID(cls, name, "I");
return env->GetStaticIntField(cls, handle);
}
JNIEXPORT void JNICALL Java_sun_jkernel_DownloadManager_displayError
(JNIEnv *env, jclass dm, jint code, jstring arg) {
int messageId = IDS_FATAL_ERROR;
int titleId = IDS_ERROR_CAPTION;
if (code == getConstantInt(env, dm, "ERROR_MALFORMED_BUNDLE_PROPERTIES"))
messageId = IDS_ERROR_MALFORMED_BUNDLE_PROPERTIES;
else if (code == getConstantInt(env, dm, "ERROR_DOWNLOADING_BUNDLE_PROPERTIES"))
messageId = IDS_ERROR_DOWNLOADING_BUNDLE_PROPERTIES;
else if (code == getConstantInt(env, dm, "ERROR_MALFORMED_URL"))
messageId = IDS_ERROR_MALFORMED_URL;
char message[BUFFER_SIZE];
char rawMessage[BUFFER_SIZE];
char title[BUFFER_SIZE];
::LoadString(_Module.GetModuleInstance(), titleId, title, BUFFER_SIZE);
::LoadString(_Module.GetModuleInstance(), messageId, rawMessage, BUFFER_SIZE);
if (arg != NULL) {
char *chars = getStringPlatformChars(env, arg);
sprintf(message, rawMessage, chars);
}
else
strcpy(message, rawMessage);
MessageBox(NULL, message, title, MB_OK|MB_TASKMODAL);
}
JNIEXPORT jboolean JNICALL Java_sun_jkernel_DownloadManager_askUserToRetryDownloadOrQuit
(JNIEnv *env, jclass dm, jint code) {
int ret;
if (code == getConstantInt(env, dm, "ERROR_DISK_FULL")) {
ret = dlg.SafeMessageBox(IDS_DISK_FULL_ERROR,
IDS_DISK_FULL_ERROR_CAPTION,
IDS_ERROR_CAPTION,
DIALOG_ERROR_RETRYCANCEL);
} else {
ret = dlg.SafeMessageBox(IDS_DOWNLOAD_RETRY_TEXT,
IDS_DOWNLOAD_RETRY,
IDS_ERROR_CAPTION,
DIALOG_ERROR_RETRYCANCEL);
}
if (ret != IDRETRY) {
// user choose to exit, return 0
return JNI_FALSE;
}
// return 1 (retry the download)
return JNI_TRUE;
}
JNIEXPORT void JNICALL Java_sun_jkernel_DownloadManager_startBackgroundDownloadWithBrokerImpl
(JNIEnv *env, jclass dm, jstring command) {
char* szCommand = getStringPlatformChars(env, command);
// Send createprocess message
char * createproccmd = "STARTBACKGROUNDDOWNLOAD";
char * msg = (char*)malloc((strlen(createproccmd) + strlen(szCommand) + 2) * sizeof(char));
sprintf(msg, "%s*%s", createproccmd, szCommand);
sendMessageToBroker(msg);
free(szCommand);
}
void getParent(const TCHAR *path, TCHAR *dest) {
char* lastSlash = max(strrchr(path, '\\'), strrchr(path, '/'));
if (lastSlash == NULL) {
*dest = NULL;
return;
}
if (path != dest)
strcpy(dest, path);
*lastSlash = NULL;
}
bool createProcess(const TCHAR *path, const TCHAR *args) {
SHELLEXECUTEINFOA shInfo;
shInfo.cbSize = sizeof(SHELLEXECUTEINFOA);
shInfo.fMask = 0;
shInfo.hwnd = NULL;
shInfo.lpVerb = "runas";
shInfo.lpFile = path;
shInfo.lpParameters = args;
shInfo.lpDirectory = NULL;
shInfo.nShow = SW_NORMAL;
shInfo.hInstApp = NULL;
int result = (int) ::ShellExecuteExA(&shInfo);
// ShellExecute is documented to return >32 on success, but I'm consistently
// getting a return of 1 despite obviously successful results. 1 is not a
// documented return code from ShellExecute, and this may have something to
// do with the fact that we're using an undocumented verb in the first place
// ("runas").
return result > 32 || result == 1;
}
bool launchJBroker(const char *szJavaHome) {
char szPath[2048];
wsprintf(szPath, "%s\\bin\\jbroker.exe", szJavaHome);
return createProcess(szPath, NULL);
}
JNIEXPORT jboolean JNICALL Java_sun_jkernel_DownloadManager_launchJBroker
(JNIEnv *env, jclass dm, jstring javaHomePath) {
char* szJavaHome = getStringPlatformChars(env, javaHomePath);
bool result = launchJBroker(szJavaHome);
free(szJavaHome);
return result ? TRUE : FALSE;
}
bool isJBrokerRunning() {
HANDLE hMutex = NULL;
DWORD ret = 0;
if (isRunningIEProtectedMode()) {
// check if jbroker process is running
// Use OpenMutex since we have limited access rights.
// CreateMutex function will fail with ERROR_ACCESS_DENIED in protected mode
hMutex = OpenMutex(SYNCHRONIZE, FALSE, "SunJavaBrokerMutex");
ret = ::GetLastError();
if (hMutex != NULL) {
CloseHandle(hMutex);
}
if (ret == ERROR_FILE_NOT_FOUND)
{
// jbroker not running yet, launch it
return FALSE;
}
return TRUE;
} else {
hMutex = ::CreateMutex(NULL, TRUE, "SunJavaBrokerMutex");
if ( (hMutex == NULL) || (::GetLastError() == ERROR_ALREADY_EXISTS)) {
// jbroker already running
if (hMutex != NULL) ::CloseHandle(hMutex);
return TRUE;
}
if (hMutex != NULL) ::CloseHandle(hMutex);
return FALSE;
}
}
JNIEXPORT jboolean JNICALL Java_sun_jkernel_DownloadManager_isJBrokerRunning
(JNIEnv *env, jclass dm) {
return isJBrokerRunning() ? TRUE : FALSE;
}
JNIEXPORT jboolean JNICALL Java_sun_jkernel_DownloadManager_moveDirWithBrokerImpl
(JNIEnv *env, jclass dm, jstring fromPath, jstring userHome) {
char* fromPathChars = getStringPlatformChars(env, fromPath);
char* userHomeChars = getStringPlatformChars(env, userHome);
int ret = sendMoveDirMessageToBroker(fromPathChars, userHomeChars);
free(fromPathChars);
free(userHomeChars);
if (ret == 0) {
return FALSE;
}
return TRUE;
}
JNIEXPORT jboolean JNICALL Java_sun_jkernel_DownloadManager_moveFileWithBrokerImpl
(JNIEnv *env, jclass dm, jstring fromPath, jstring userHome) {
char* fromPathChars = getStringPlatformChars(env, fromPath);
char* userHomeChars = getStringPlatformChars(env, userHome);
int ret = sendMoveMessageToBroker(fromPathChars, userHomeChars);
free(fromPathChars);
free(userHomeChars);
if (ret == 0) {
return FALSE;
}
return TRUE;
}
/**
* Throw an exception with the last Windows error code if available.
*/
void ThrowByNameWithLastError(JNIEnv *env, char *exception, char* msg) {
char fullMsg[1024] = {0};
if (StringCbPrintf(fullMsg, 1024, "%s. Windows error: %d\n",
msg, GetLastError()) != S_OK) {
// Formatting failed: fall back to msg w/o error code
ThrowByName(env, exception, msg);
} else {
ThrowByName(env, exception, fullMsg);
}
}
/**
* Common code for "extra" compression or uncompression. If extra code
* not available do nothing but return false. If available, return true
* after locating the extra compression library at ".." and the defined
* path relative to the native library containing this method's code.
* If enabled, compress or uncompress the srcPath file into destpath,
* throwing exceptions for errors (see JNI routine docs below for details).
*/
jboolean extraCommon(BOOL docompress,
JNIEnv *env, jclass dm, jstring srcPath, jstring destPath) {
#ifdef EXTRA_COMP_INSTALL_PATH
const char *operation = (docompress == true) ? "e" : "d";
// This should be shared with the deploy tree and should be defined
// in an implementation like LzmaAlone.h. However the deploy build
// doesn't exit yet wrt to this function pointer type.
typedef int (*EXTRACOMPTRTYPE) (int, const char**);
// Function pointer for invoking the encoder/decoder (uncompressor)
static volatile EXTRACOMPTRTYPE mptr = NULL;
// Volatile boolean becomes true when mptr init is finished
// Stringifier macros to get the relative library path
#define K_STRING(x) #x
#define K_GETSTRING(x) K_STRING(x)
char *srcPathChars = getStringPlatformChars(env, srcPath);
if (srcPathChars == NULL) {
// TODO (for all throw calls). If the class&method are *reliably*
// reported to the user these message prefixes are silly.
ThrowByName(env, "java/io/IOException",
"Bundle.uncompress: GetStringPlatformChars failed");
return true;
}
char *destPathChars = getStringPlatformChars(env, destPath);
if (destPathChars == NULL) {
free(srcPathChars);
ThrowByName(env, "java/io/IOException",
"Bundle.uncompress: GetStringPlatformChars failed");
return true;
}
if (KERNEL_DEBUG) {
printf("LZMA: %s %s to %s\n", operation, srcPathChars, destPathChars);
}
// This loop avoids a lot of repetitious code for exception handling.
// If any loops are put inside this one be careful to properly
// handle exceptions within the inner loops.
do {
if (mptr == NULL) {
// Need to locate and link to the extra compression lib, which
// has a pathname relative to the directory containing the library
// containing this code, which is assumed to be one directory
// "below" the JRE base path. That is, the JRE base path is
// assumed to be ".." from the path of this library and then
// EXTRA_COMP_INSTALL_PATH from the JRE base path is expected to
// be the compression lib path.
// But this code is defensive and tries not to fail if the
// currently executing library is in ".". It will fail in a
// case like this if the extra compression lib path isn't
// "./EXTRA_CMP_INSTALL_PATH" (or just "EXTRA_CMP_INSTALL_PATH").
// Use macro magic to get the path macro as a string value.
const char *libRelativePath = K_GETSTRING(EXTRA_COMP_INSTALL_PATH);
// The max length the base JRE path can be to safely concatenate
// libRelativePath, a (possible) separator, and a null terminator.
int jreMaxPathLength = MAX_PATH - sizeof(libRelativePath) - 2;
TCHAR extraLibPath[MAX_PATH] = {0};
HMODULE kernel = GetModuleHandle("jkernel");
if (kernel != NULL) {
DWORD result = GetModuleFileName(kernel, extraLibPath,
MAX_PATH-1);
if (result > 0) {
// remove the name of this library (and maybe a
// separator)
getParent(extraLibPath, extraLibPath);
if (extraLibPath[0] != NULL) {
// There was a directory containing the library
// (probably "<something or nothing\\>bin"), so
// remove that to go up to the assumed JRE base path
getParent(extraLibPath, extraLibPath);
} else {
ThrowByName(env, "java/io/IOException",
"bundle uncompression: expected lib path component not found");
break;
}
// This is effectively an assertion that the concat
// below cannot overflow
if (extraLibPath[0] != NULL) {
// Current dir is not ".", so add a separator
strcat(extraLibPath, "\\");
}
if ((strlen(extraLibPath) + 1) > jreMaxPathLength) {
ThrowByName(env, "java/io/IOException",
"bundle uncompression: JRE base pathname too long");
break;
}
strcat(extraLibPath, libRelativePath);
} else {
ThrowByName(env, "java/io/IOException",
"bundle uncompression: GetModuleFileName failed");
break;
}
} else {
ThrowByNameWithLastError(env, "java/io/IOException",
"bundle uncompression: GetModuleHandle failed");
break;
}
// Load the library and develop a pointer to the decoder routine
if (KERNEL_DEBUG) {
printf("bundle uncompression: extra library path %s\n",
extraLibPath);
}
HMODULE handle = LoadLibrary(extraLibPath);
if (handle == NULL) {
ThrowByNameWithLastError(env, "java/io/IOException",
"bundle uncompression: LoadLibrary failed");
break;
}
// find the extra uncompression routine
mptr = (EXTRACOMPTRTYPE) GetProcAddress(handle,
"ExtraCompressionMain");
if (mptr == NULL) {
ThrowByNameWithLastError(env, "java/io/IOException",
"bundle uncompression: GetProcAddress failed");
break;
}
}
// Create the arguments for the decoder
// Decoder options must go *between* the "d" argument and the
// source path arguments and don't forget to keep the 1st arg to
// (*mptr) the same as the number of elements of args.
const char *args[] = {
"", // the shared lib makes no attempt access it's "command name"
operation,
// Special decoder/encoder switch strings would go here
// For example: "-d24", to set the dictionary size to 16MB
"-q", // Suppress banner msg output
// No special option switch strings after here
srcPathChars,
destPathChars
};
int argc = sizeof(args) / sizeof(const char *);
if ((*mptr)(argc, args) != 0) {
if (KERNEL_DEBUG) {
printf("uncompress lib call failed with args: ");
for (int i = 0; i < argc; i++) {
printf("%s", args[i]);
}
printf("\n");
}
ThrowByName(env, "java/io/IOException",
"bundle uncompression: uncompression failed");
break;
}
} while (false);
free(srcPathChars);
free(destPathChars);
return TRUE;
#else
if (KERNEL_DEBUG) {
printf("LZMA not compiled in!\n");
}
return FALSE;
#endif // EXTRA_COMP_INSTALL_PATH
}
/**
* Compress file sourcePath with "extra" algorithm (e.g. 7-Zip LZMA)
* if available, put the compressed data into file destPath and
* return true. If extra compression is not available do nothing
* with destPath and return false;
* @param srcPath the path of the uncompressed file
* @param destPath the path of the compressed file, if used
* @return true if the extra algorithm was used and destPath created
*
* @throws IOException if the extra compression code should be available
* but cannot be located or linked to, the destination file already
* exists or cannot be opened for writing, or the compression fails
*/
JNIEXPORT jboolean JNICALL Java_sun_jkernel_Bundle_extraCompress
(JNIEnv *env, jclass dm, jstring srcPath, jstring destPath) {
return extraCommon(true, env, dm, srcPath, destPath);
}
/**
* Uncompress file sourcePath with "extra" algorithm (e.g. 7-Zip LZMA)
* if available, put the uncompressed data into file destPath and
* return true. If if the extra algorithm is not available, leave the
* destination path unchanged and return false;
* @param srcPath the path of the file having extra compression
* @param destPath the path of the uncompressed file
* @return true if the extra algorithm was used
*
* @throws IOException if the extra uncompression code should be available
* but cannot be located or linked to, the destination file already
* exists or cannot be opened for writing, or the uncompression fails
*/
JNIEXPORT jboolean JNICALL Java_sun_jkernel_Bundle_extraUncompress
(JNIEnv *env, jclass dm, jstring srcPath, jstring destPath) {
return extraCommon(false, env, dm, srcPath, destPath);
}
JNIEXPORT void JNICALL Java_sun_jkernel_DownloadManager_addToTotalDownloadSize
(JNIEnv *env, jclass dm, jint size) {
dlg.addToTotalContentLength(size);
}
JNIEXPORT void JNICALL Java_sun_jkernel_DownloadManager_downloadFromURLImpl
(JNIEnv *env, jclass dm, jstring url, jobject file, jstring name,
jboolean showProgress) {
jclass object = env->FindClass("java/lang/Object");
jmethodID toString = env->GetMethodID(object, "toString", "()Ljava/lang/String;");
jstring urlString = (jstring) env->CallObjectMethod(url, toString);
char* urlChars = getStringPlatformChars(env, urlString);
if (KERNEL_DEBUG) {
printf("Kernel downloadFromURL: %s\n", urlChars);
}
jstring fileString = (jstring) env->CallObjectMethod(file, toString);
char* fileChars = getStringPlatformChars(env, fileString);
char* nameChars = getStringPlatformChars(env, name);
JavaVM *jvm;
env->GetJavaVM(&jvm);
__try
{
m_csCreateDialog.Lock();
if (createDialog && showProgress) {
// create download progress dialog in a new thread
dlg.setJavaVM(jvm);
createDownloadWindow(&dlg);
createDialog = FALSE;
}
}
__finally
{
m_csCreateDialog.Unlock();
}
DownloadHelper dh;
dh.setJavaVM(jvm);
dh.setURL(urlChars);
dh.setFile(fileChars);
dh.setNameText((char*) nameChars);
dh.setShowProgressDialog(showProgress);
dh.setDownloadDialog(&dlg);
if (dh.doDownload() != S_OK) {
// remove incomplete file
int ret = DeleteFile(fileChars);
}
free(urlChars);
free(fileChars);
free(nameChars);
}
void error(char* msg) {
MessageBox(NULL, msg, "Java Error", MB_OK);
}
// Replace the dest file with the src file. Returns zero on success, Windows
// error code otherwise.
int replace(TCHAR* fullDest, TCHAR* fullSrc) {
struct _stat stat;
int result = _stat(fullSrc, &stat);
if (result == 0) {
DeleteFile(fullDest);
if (MoveFile(fullSrc, fullDest))
return 0;
else
return GetLastError();
}
else
return ENOENT; // src file not found
}
// Replace the dest file with the src file, where both paths are relative to
// the specified root. Returns zero on success, Windows error code otherwise.
int replaceRelative(TCHAR* root, TCHAR* dest, TCHAR* src) {
TCHAR fullDest[MAX_PATH];
TCHAR fullSrc[MAX_PATH];
strcpy(fullDest, root);
strcat(fullDest, dest);
strcpy(fullSrc, root);
strcat(fullSrc, src);
return replace(fullDest, fullSrc);
}
// Atomically deletes a file tree. Returns zero on success, Windows
// error code otherwise.
int deleteAll(TCHAR* root) {
TCHAR tmp[MAX_PATH];
if (strlen(root) + 5 > MAX_PATH)
return ERROR_BUFFER_OVERFLOW;
strcpy(tmp, root);
strcat(tmp, ".tmp");
struct _stat stat;
int result = _stat(tmp, &stat);
if (result == 0) {
result = !deleteAll(tmp);
if (result)
return result;
}
if (!MoveFile(root, tmp))
return GetLastError();
struct _SHFILEOPSTRUCTA fileOp;
memset(&fileOp, NULL, sizeof(fileOp));
fileOp.wFunc = FO_DELETE;
TCHAR pFrom[MAX_PATH + 1];
strcpy(pFrom, tmp);
pFrom[strlen(pFrom) + 1] = NULL; // extra null to signify that there is only one file in the list
fileOp.pFrom = pFrom;
fileOp.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
return SHFileOperation(&fileOp);
}
// moves all file with "wait='true'" specified in bundles.xml into their final
// locations. These files are stored under lib/bundles/tmp, e.g. lib/meta-index
// is stored at lib/bundles/tmp/lib/meta-index.
// relativePath is the current relative path we are searching (e.g. "lib" for the
// example above), which begins as the empty string.
int moveDelayedFiles(TCHAR* javaHome, TCHAR* relativePath) {
TCHAR src[MAX_PATH];
TCHAR* tmp = "lib\\bundles\\tmp";
if (strlen(javaHome) + strlen(relativePath) + strlen(tmp) > MAX_PATH) {
error("Path too long.");
return ERROR_BUFFER_OVERFLOW;
}
strcpy(src, javaHome);
strcat(src, tmp);
if (relativePath[0] != NULL) {
strcat(src, "\\");
strcat(src, relativePath);
}
struct _stat stat;
int result = _stat(src, &stat);
if (result == 0) {
if (stat.st_mode & _S_IFDIR) { // is a directory, loop through contents
strcat(src, "\\*");
struct _WIN32_FIND_DATAA file;
HANDLE findHandle = FindFirstFile(src, &file);
if (findHandle != INVALID_HANDLE_VALUE) {
do {
if (file.cFileName[0] != '.') {
char child[MAX_PATH];
strcpy(child, relativePath);
strcat(child, "\\");
strcat(child, file.cFileName);
moveDelayedFiles(javaHome, child);
}
}
while (FindNextFile(findHandle, &file) != 0);
FindClose(findHandle);
}
}
else { // normal file, move into place
if (strcmp(relativePath, "\\finished")) {
TCHAR dest[MAX_PATH];
strcpy(dest, javaHome);
strcat(dest, relativePath);
DeleteFile(dest); // just in case; ignore failures
if (MoveFile(src, dest))
return 0;
else
return GetLastError();
}
}
}
return result;
}
// activates Class Data Sharing
void activateCDS(const char *javaHome) {
char java[MAX_PATH];
strcpy(java, javaHome);
strcat(java, "bin\\javaw.exe");
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
const char *args = " -Xshare:dump";
const int argLength = 13;
char commandLine[MAX_PATH + argLength + 2];
strcpy(commandLine, "\"");
strcat(commandLine, java);
strcat(commandLine, "\"");
strcat(commandLine, args);
if (KERNEL_DEBUG)
printf("Exec: %s\n", commandLine);
if (CreateProcess(java, commandLine, NULL, NULL, FALSE, 0,
NULL, NULL, &si, &pi)) {
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
else
printf("Error initializing Class Data Sharing: %d", GetLastError());
}
typedef BOOL (*LPFNInstallJQS)();
// activates the Java Quickstart Service
void activateJQS(HMODULE hModule) {
LPFNInstallJQS lpfnInstallJQS;
if (hModule != NULL) {
lpfnInstallJQS = (LPFNInstallJQS)GetProcAddress(hModule, "InstallJQS");
if (lpfnInstallJQS != NULL) {
if ((lpfnInstallJQS)() == false && KERNEL_DEBUG) {
printf("InstallJQS returned FALSE\n");
}
}
}
}
// determines JAVA_HOME and stores it in the specified buffer. Returns true on success.
BOOL getJavaHome(char* buffer, int bufferSize) {
HMODULE kernel = GetModuleHandle("jkernel");
if (kernel != NULL) {
DWORD result = GetModuleFileName(kernel, buffer, bufferSize);
if (result > 0) {
getParent(buffer, buffer); // remove "jkernel.dll"
if (buffer[0] != NULL)
getParent(buffer, buffer); // remove "bin"
if (buffer[0] != NULL) {
strcat(buffer, "\\");
return TRUE;
}
}
}
return FALSE;
}
typedef unsigned int (WINAPI *LPFNPostPing)(LPVOID err);
HANDLE PostPing(HMODULE hModule, char* fname, DWORD err)
{
LPFNPostPing lpfnPostPing;
HANDLE hThread = NULL;
lpfnPostPing = (LPFNPostPing)GetProcAddress(hModule, fname);
if (lpfnPostPing != NULL) {
printf("############# ERROR CODE: %d\n", err);
hThread = (HANDLE)_beginthreadex(NULL, 0, lpfnPostPing,
(LPVOID)err, 0, NULL);
if (hThread == NULL)
lpfnPostPing((LPVOID)err);
}
return hThread;
}
void postPingAndWait(char* fname, DWORD err) {
TCHAR path[MAX_PATH];
if (getJavaHome(path, MAX_PATH)) {
strcat(path, "bin\\regutils.dll");
HANDLE hThread = NULL;
HMODULE hModule = LoadLibrary(path);
if (hModule != NULL) {
hThread = PostPing(hModule, fname, err);
if (hThread != NULL) {
DWORD dwRet = 0;
WaitForSingleObject(hThread, 60*1000);
GetExitCodeThread(hThread, &dwRet);
CloseHandle(hThread);
}
}
}
else
printf("error determining JAVA_HOME for ping\n");
}
JNIEXPORT void JNICALL Java_sun_jkernel_DownloadManager_postDownloadError
(JNIEnv *env, jclass dm, jint error) {
postPingAndWait("PostKernelDLComp", error);
}
JNIEXPORT void JNICALL Java_sun_jkernel_DownloadManager_postDownloadComplete
(JNIEnv *env, jclass dm) {
Java_sun_jkernel_DownloadManager_postDownloadError(env, dm, ERROR_SUCCESS);
}
bool spawnedFromJBroker() {
return strstr(GetCommandLine(), JBROKER_KEY) != NULL;
}
// Determines if we have sufficient access to go ahead and perform completion.
// This is true either if we are not on Vista (in which case we can't elevate
// privileges anyway and have to hope for the best) or if we are on Vista and
// running at High integrity level.
bool highIntegrity() {
if (!IsPlatformWindowsVista())
return TRUE;
else {
// directly determining this would require access to Vista-specific
// APIs, which aren't supported by our current build configurations.
// Instead we look for the presence of a flag on the command line to
// indicate that we were launched by the jbroker process. This is
// actually safer, as it prevents us from re-launching another JRE in
// the event that we somehow didn't end up with high integrity.
return spawnedFromJBroker();
}
}
JNIEXPORT jint JNICALL Java_sun_jkernel_DownloadManager_getCurrentProcessId
(JNIEnv *env, jclass dm) {
return (jint) GetCurrentProcessId();
}
JNIEXPORT jstring JNICALL Java_sun_jkernel_DownloadManager_getVisitorId0
(JNIEnv *env, jclass dm) {
CRegKey swKey, jsKey, juKey, pKey;
if (swKey.Open(HKEY_LOCAL_MACHINE, "SOFTWARE", KEY_READ) != ERROR_SUCCESS){
return NULL;
}
if (jsKey.Open(swKey, "JavaSoft", KEY_READ) != ERROR_SUCCESS){
return NULL;
}
if (juKey.Open(jsKey, "Java Update", KEY_READ) != ERROR_SUCCESS){
return NULL;
}
if (pKey.Open(juKey, "Policy", KEY_READ) != ERROR_SUCCESS){
return NULL;
}
DWORD dwCount = BUFSIZE;
char* keyValue = new char[BUFSIZE];
if (pKey.QueryValue(keyValue, "VisitorId", &dwCount) != ERROR_SUCCESS){
return NULL;
}
jstring visitorId = env->NewStringUTF(keyValue);
return visitorId;
}
JNIEXPORT jstring JNICALL Java_sun_jkernel_DownloadManager_getUrlFromRegistry
(JNIEnv *env, jclass dm) {
CRegKey swKey, jsKey;
if (swKey.Open(HKEY_LOCAL_MACHINE, "SOFTWARE", KEY_READ) != ERROR_SUCCESS){
return NULL;
}
if (jsKey.Open(swKey, "JavaSoft", KEY_READ) != ERROR_SUCCESS){
return NULL;
}
DWORD dwCount = BUFSIZE;
char * keyValue = new char[BUFSIZE];
if (jsKey.QueryValue(keyValue, "KernelDownloadUrl", &dwCount) != ERROR_SUCCESS){
return NULL;
}
jstring downloadKeyValue = env->NewStringUTF(keyValue);
return downloadKeyValue;
}
jboolean getBooleanRegistryKey(char *name, jboolean defaultValue) {
// Check DWORD registry key
// HKEY_LOCAL_MACHINE/Software/JavaSoft/<name>
CRegKey swKey, jsKey;
if (swKey.Open(HKEY_LOCAL_MACHINE, "SOFTWARE", KEY_READ) != ERROR_SUCCESS){
return NULL;
}
if (jsKey.Open(swKey, "JavaSoft", KEY_READ) != ERROR_SUCCESS){
return NULL;
}
DWORD dwValue = 0;
if (jsKey.QueryValue(dwValue, name) != ERROR_SUCCESS){
// Key does not exist, will return default value
return defaultValue;
}
return dwValue != 0;
}
JNIEXPORT jboolean JNICALL Java_sun_jkernel_BackgroundDownloader_getBackgroundDownloadKey
(JNIEnv *env, jclass dm) {
return getBooleanRegistryKey("KernelBackgroundDownload", TRUE);
}
JNIEXPORT jboolean JNICALL Java_sun_jkernel_DownloadManager_getDebugKey
(JNIEnv *env, jclass dm) {
return getBooleanRegistryKey("KernelDebug", FALSE);
}
// Called by the launcher before the JVM starts. If all kernel bundles have been
// downloaded, this function performs various post-download cleanups such as
// moving the merged rt.jar into place. At the end of cleanup, the JRE should
// be indistinguishable from the non-kernel JRE.
void preJVMStart() {
char rawMsg[BUFFER_SIZE];
char msg[BUFFER_SIZE];
HMODULE kernel = GetModuleHandle("jkernel");
if (kernel != NULL) {
TCHAR javaHome[MAX_PATH];
DWORD result = GetModuleFileName(kernel, javaHome, MAX_PATH);
if (result > 0) {
getParent(javaHome, javaHome); // remove "jkernel.dll"
if (javaHome[0] != NULL)
getParent(javaHome, javaHome); // remove "bin"
if (javaHome[0] != NULL) {
// should now be pointing to correct java.home
strcat(javaHome, "\\");
bool jbroker = spawnedFromJBroker();
HANDLE file;
TCHAR rt[MAX_PATH];
strcpy(rt, javaHome);
strcat(rt, "lib\\rt.jar");
HANDLE startMutex = CreateMutex(NULL, FALSE, "jvmStart");
if (!jbroker) { // else mutex is already held by the pre-jbroker JVM
if (KERNEL_DEBUG)
printf("Locking startMutex\n");
WaitForSingleObject(startMutex, INFINITE);
if (KERNEL_DEBUG)
printf("Locked startMutex\n");
// open rt.jar for reading. This prevents other JREs from being
// able to acquire a write lock on rt.jar, which is used as a test
// to ensure that no other JREs are running.
// The failure to close the file handle is intentional -- if we
// close it, there will be a brief window between the close and
// when the JRE reopens it during which another jre could get
// a write lock on it, hosing us.
file = CreateFile(rt, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
if (file == INVALID_HANDLE_VALUE) {
ReleaseAndClose(startMutex);
return;
}
if (KERNEL_DEBUG)
printf("Opened rt.jar for reading\n");
}
TCHAR finished[MAX_PATH];
TCHAR* finishedPath = "lib\\bundles\\tmp\\finished";
if (strlen(javaHome) + strlen(finishedPath) < MAX_PATH) {
strcpy(finished, javaHome);
strcat(finished, finishedPath);
struct _stat finishedStat;
result = _stat(finished, &finishedStat);
if (result == 0) { // JRE has been fully downloaded but not yet cleaned up
if (KERNEL_DEBUG)
printf("Beginning completion.\n");
if (!jbroker)
CloseHandle(file);
if (highIntegrity()) {
// attempt to open rt.jar for exclusive write access -- if this succeeds,
// we know no other JREs are running
file = CreateFile(rt, GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, NULL, NULL);
if (file == INVALID_HANDLE_VALUE) {
// must be another JRE running...
ReleaseAndClose(startMutex);
return;
}
if (KERNEL_DEBUG)
printf("Opened rt.jar for writing.\n");
CloseHandle(file);
if (KERNEL_DEBUG)
printf("Closed rt.jar.\n");
int result = replaceRelative(javaHome, "lib\\rt.jar",
"lib\\bundles\\tmp\\merged-rt.jar");
if (result != 0 && result != ENOENT) {
::LoadString(_Module.GetModuleInstance(), IDS_FILE_UPDATE_ERROR, rawMsg, BUFFER_SIZE);
wsprintf(msg, rawMsg, javaHome, "lib\\rt.jar");
error(msg);
ReleaseAndClose(startMutex);
return;
}
result = replaceRelative(javaHome, "lib\\resources.jar",
"lib\\bundles\\tmp\\merged-resources.jar");
if (result != 0 && result != ENOENT) {
::LoadString(_Module.GetModuleInstance(), IDS_FILE_UPDATE_ERROR, rawMsg, BUFFER_SIZE);
wsprintf(msg, rawMsg, javaHome, "lib\\resources.jar");
error(msg);
ReleaseAndClose(startMutex);
return;
}
TCHAR bundles[MAX_PATH];
strcpy(bundles, javaHome);
strcat(bundles, "lib\\bundles");
if (moveDelayedFiles(javaHome, "")) {
::LoadString(_Module.GetModuleInstance(), IDS_FILE_UPDATE_ERROR, msg, BUFFER_SIZE);
error(msg);
ReleaseAndClose(startMutex);
return;
}
TCHAR kernel[MAX_PATH];
strcpy(kernel, javaHome);
strcat(kernel, "bin\\kernel");
result = deleteAll(kernel);
if (result != 0 && result != ENOENT) {
::LoadString(_Module.GetModuleInstance(), IDS_FILE_DELETE_ERROR, rawMsg, BUFFER_SIZE);
wsprintf(msg, rawMsg, kernel);
error(msg);
ReleaseAndClose(startMutex);
return;
}
if (deleteAll(bundles)) {
// fail silently, CR #6643218
printf("deleteAll failed!\n");
ReleaseAndClose(startMutex);
return;
}
TCHAR kernelMap[MAX_PATH];
strcpy(kernelMap, javaHome);
strcat(kernelMap, "lib\\kernel.map");
result = deleteAll(kernelMap);
if (result != 0 && result != ENOENT) {
::LoadString(_Module.GetModuleInstance(), IDS_FILE_DELETE_ERROR, rawMsg, BUFFER_SIZE);
wsprintf(msg, rawMsg, kernelMap);
error(msg);
ReleaseAndClose(startMutex);
return;
}
strcpy(rt, javaHome);
strcat(rt, "bin\\regutils.dll");
HANDLE hThread = NULL;
HMODULE hModule = LoadLibrary(rt);
if (hModule != NULL)
hThread = PostPing(hModule, "PostKernelComp", ERROR_SUCCESS);
if (KERNEL_DEBUG)
printf("Activating JQS.\n");
activateJQS(hModule);
if (KERNEL_DEBUG)
printf("Activating CDS.\n");
activateCDS(javaHome);
if (hThread != NULL) {
DWORD dwRet = 0;
WaitForSingleObject(hThread, 60*1000);
GetExitCodeThread(hThread, &dwRet);
CloseHandle(hThread);
}
if (hModule != NULL)
FreeLibrary(hModule);
} else {
bool jbroker = isJBrokerRunning();
if (!jbroker) {
// remove trailing slash
javaHome[strlen(javaHome) - 1] = 0;
jbroker = launchJBroker(javaHome);
if (!jbroker) {
::LoadString(_Module.GetModuleInstance(),
IDS_JBROKER_ERROR,
msg,
BUFFER_SIZE);
error(msg);
}
}
if (jbroker)
sendPerformCompletionMessageToBroker(javaHome);
}
}
}
if (KERNEL_DEBUG)
printf("Releasing startMutex.\n");
ReleaseAndClose(startMutex);
} else {
::LoadString(_Module.GetModuleInstance(), IDS_JAVA_HOME_ERROR, msg, BUFFER_SIZE);
error(msg);
}
} else {
::LoadString(_Module.GetModuleInstance(), IDS_KERNEL_HOME_ERROR, msg, BUFFER_SIZE);
error(msg);
}
} else {
::LoadString(_Module.GetModuleInstance(), IDS_KERNEL_HOME_ERROR, msg, BUFFER_SIZE);
error(msg);
}
}
;
; Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
; DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
;
; This code is free software; you can redistribute it and/or modify it
; under the terms of the GNU General Public License version 2 only, as
; published by the Free Software Foundation. Sun designates this
; particular file as subject to the "Classpath" exception as provided
; by Sun in the LICENSE file that accompanied this code.
;
; This code is distributed in the hope that it will be useful, but WITHOUT
; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
; version 2 for more details (a copy is included in the LICENSE file that
; accompanied this code).
;
; You should have received a copy of the GNU General Public License version
; 2 along with this work; if not, write to the Free Software Foundation,
; Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
;
; Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
; CA 95054 USA or visit www.sun.com if you need additional information or
; have any questions.
;
LIBRARY jkernel
EXPORTS
preJVMStart @1
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
void preJVMStart();
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
#include "version.rc"
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
#include "afxres.h"
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
IDI_JAVA ICON DISCARDABLE "graphics\\java-icon.ico"
IDI_MASTHEAD BITMAP DISCARDABLE "graphics\\masthead.bmp"
/////////////////////////////////////////////////////////////////////////////
// Include foreign resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Japanese resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN)
#ifdef _WIN32
LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT
#pragma code_page(932)
#endif //_WIN32
#include "kernel_ja.rc"
#endif // Japanese resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Chinese (P.R.C.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
#ifdef _WIN32
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#pragma code_page(936)
#endif //_WIN32
#include "kernel_zh.rc"
#endif // Chinese (P.R.C.) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Korean resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_KOR)
#ifdef _WIN32
LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT
#pragma code_page(949)
#endif //_WIN32
#include "kernel_ko.rc"
#endif // Korean resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Chinese (Taiwan) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHT)
#ifdef _WIN32
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL
#pragma code_page(950)
#endif //_WIN32
#include "kernel_zh_TW.rc"
#endif // Chinese (Taiwan) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// German (Germany) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
#ifdef _WIN32
LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
#pragma code_page(1252)
#endif //_WIN32
#include "kernel_de.rc"
#endif // German (Germany) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Spanish (Castilian) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ESP)
#ifdef _WIN32
LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
#pragma code_page(1252)
#endif //_WIN32
#include "kernel_es.rc"
#endif // Spanish (Castilian) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// French (France) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA)
#ifdef _WIN32
LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
#pragma code_page(1252)
#endif //_WIN32
#include "kernel_fr.rc"
#endif // French (France) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Italian (Italy) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ITA)
#ifdef _WIN32
LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL
#pragma code_page(1252)
#endif //_WIN32
#include "kernel_it.rc"
#endif // Italian (Italy) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Swedish resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_SVE)
#ifdef _WIN32
LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL
#pragma code_page(1252)
#endif //_WIN32
#include "kernel_sv.rc"
#endif // Swedish resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#include "kernel_en.rc"
#endif // English resources
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 340, 120
STYLE DS_MODALFRAME | DS_3DLOOK | DS_CENTER | WS_POPUP |
WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Zusätzliche Komponenten erforderlich"
EXSTYLE WS_EX_APPWINDOW
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "", IDC_DOWNLOAD_MASTHEAD, 0, 0, 340, 39
LTEXT "", IDC_MASTHEAD_TEXT, 60, 4, 220, 30
CONTROL "", IDC_STATIC,"Static", SS_BLACKFRAME | SS_SUNKEN,
0, 39, 340, 1
LTEXT "", IDC_DOWNLOAD_TEXT, 12, 60, 316, 20
LTEXT "", IDC_TIME_REMAINING, 12, 90, 316, 10
CONTROL "Progress1",1006,"msctls_progress32",PBS_SMOOTH,
12, 100, 265, 14
PUSHBUTTON "Abbrechen", 2, 285, 100, 46, 14
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
105, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 236
TOPMARGIN, 7
BOTTOMMARGIN, 63
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_DOWNLOAD_CANCEL_MESSAGE "Wenn Sie die Installation zusätzlicher Komponenten, die für die Anwendung erforderlich sind, abbrechen, wird die Anwendung möglicherweise geschlossen.\n\nMöchten Sie die Installation zusätzlicher Komponenten wirklich abbrechen?"
IDS_DOWNLOAD_CANCEL_CAPTION "Abbrechen - Zusätzliche Komponenten"
IDS_DOWNLOAD_CANCEL_INSTRUCTION ""
IDS_HTTP_INSTRUCTION_REQUEST_TIMEOUT "Verbindungszeitüberschreitung"
IDS_HTTP_INSTRUCTION_SERVER_NOT_REACHABLE "Internetverbindung kann nicht hergestellt werden"
IDS_HTTP_INSTRUCTION_UNKNOWN_ERROR "Serverfehler (Fehler %s)"
IDS_HTTP_INSTRUCTION_SERVICE_UNAVAIL "Der Dienst nicht verfügbar (Fehler %s)"
IDS_HTTP_INSTRUCTION_FORBIDDEN "Zugriff verweigert oder verboten (Fehler %s)"
IDS_HTTP_STATUS_OTHER "Bei der Anfrage ist ein Fehler aufgetreten. Möchten Sie die Anfrage wiederholen?"
// HTTP status code
IDS_HTTP_STATUS_REQUEST_TIMEOUT "Während der Server auf die Anforderung wartete, kam es zu einer Zeitüberschreitung."
IDS_HTTP_STATUS_FORBIDDEN "Der Server hat die Anforderung verstanden, verweigert jedoch deren Ausführung."
IDS_HTTP_STATUS_SERVER_ERROR "Der Server stieß auf eine unerwartete Bedingung, die das Ausführen der Anforderung verhinderte."
IDS_HTTP_STATUS_SERVICE_UNAVAIL "Der Dienst ist vorübergehend überlastet."
IDS_DOWNLOAD_STATUS_RETRY "Server beschäftigt. Erneuter Versuch in %ld Sekunden ..."
IDS_ERROR_CAPTION "Fehler - Java Kernel"
IDS_HOURSMINUTESECOND "Verbleibende Zeit (geschätzt): %d Stunden, %d Minuten und %.0f Sekunden"
IDS_HOURMINUTESECOND "Verbleibende Zeit (geschätzt): %d Stunde, %d Minuten und %.0f Sekunden"
IDS_MINUTESECOND "Verbleibende Zeit (geschätzt): %d Minuten %.0f Sekunden"
IDS_SECOND "Verbleibende Zeit (geschätzt): %.0f Sekunden"
IDS_DISK_FULL_ERROR_CAPTION "Festplatte voll"
IDS_DISK_FULL_ERROR "Java Kernel konnte erforderliche Komponenten nicht herunterladen, da der Datenträger voll ist. Noch einmal versuchen?"
IDS_DISK_WRITE_ERROR_CAPTION "Fehler beim Schreiben auf Datenträger"
IDS_DISK_WRITE_ERROR "Java Kernel hat beim Schreiben uf den Datenträger einen Fehler verursacht Noch einmal versuchen?"
IDS_HTTP_STATUS_SERVER_NOT_REACHABLE "Java Kernel kann aufgrund der aktuellen Internetverbindungseinstellungen Ihres Systems nicht fortfahren. Überprüfen Sie in der Windows-Systemsteuerung unter 'Internetoptionen -> Verbindungen' die Einstellungen und Proxy-Angaben."
IDS_DOWNLOAD_RETRY "Downloadfehler"
IDS_DOWNLOAD_RETRY_TEXT "Beim Herunterladen einiger benötigter Komponenten ist ein Fehler aufgetreten. Möchten Sie noch einmal versuchen, diese Komponenten herunterzuladen?"
IDS_DOWNLOAD "Zusätzliche Komponenten werden installiert."
IDS_DOWNLOAD_UNPACKING "Entpacken des Pakets"
IDS_DOWNLOAD_TEXT "Die Java-Anwendung wird starten, sobald zusätzliche Komponenten heruntergeladen und installiert sind."
IDS_FILE_UPDATE_ERROR "Beim Aktualisieren von %s%s ist ein Fehler aufgetreten."
IDS_FILE_DELETE_ERROR "Beim Entfernen von %s ist ein Fehler aufgetreten."
IDS_JAVA_HOME_ERROR "Java-Verzeichnis kann nicht ermittelt werden."
IDS_KERNEL_HOME_ERROR "Pfad der jkernel.dll kann nicht ermittelt werden."
IDS_JBROKER_ERROR "jbroker.exe kann nicht gestartet werden."
IDS_FATAL_ERROR "Java konnte einige erforderliche Komponenten nicht herunterladen. Das Programm wird geschlossen."
IDS_ERROR_DOWNLOADING_BUNDLE_PROPERTIES "Java konnte keine Verbindung zum Downloadserver herstellen. Das Programm wird geschlossen."
IDS_ERROR_MALFORMED_BUNDLE_PROPERTIES "Bei der Verbindung mit dem Downloadserver ist ein Fehler aufgetreten. Das Programm wird geschlossen."
IDS_ERROR_MALFORMED_URL "Java konnte von URL '%s' keinen Dowload ausführen. Das Programm wird geschlossen."
END
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 340, 120
STYLE DS_MODALFRAME | DS_3DLOOK | DS_CENTER | WS_POPUP |
WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Additional Components Needed"
EXSTYLE WS_EX_APPWINDOW
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "", IDC_DOWNLOAD_MASTHEAD, 0, 0, 340, 39
LTEXT "", IDC_MASTHEAD_TEXT, 60, 14, 200, 12
CONTROL "", IDC_STATIC,"Static", SS_BLACKFRAME | SS_SUNKEN,
0, 39, 340, 1
LTEXT "", IDC_DOWNLOAD_TEXT, 12, 60, 316, 20
LTEXT "", IDC_TIME_REMAINING, 12, 90, 316, 10
CONTROL "Progress1",1006,"msctls_progress32",PBS_SMOOTH,
12, 100, 265, 14
PUSHBUTTON "Cancel", 2, 285, 100, 46, 14
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
105, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 236
TOPMARGIN, 7
BOTTOMMARGIN, 63
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_DOWNLOAD_CANCEL_MESSAGE "Canceling the installation of additional components which the application needs may cause the application to exit.\n\nAre you sure you want to cancel the installation of additional components?"
IDS_DOWNLOAD_CANCEL_CAPTION "Cancel - Additional Components"
IDS_DOWNLOAD_CANCEL_INSTRUCTION ""
IDS_HTTP_INSTRUCTION_REQUEST_TIMEOUT "Connection Timed Out"
IDS_HTTP_INSTRUCTION_SERVER_NOT_REACHABLE "Unable to connect to the Internet"
IDS_HTTP_INSTRUCTION_UNKNOWN_ERROR "Server error (Error %s)"
IDS_HTTP_INSTRUCTION_SERVICE_UNAVAIL "Service Unavailable (Error %s)"
IDS_HTTP_INSTRUCTION_FORBIDDEN "Access Denied or Forbidden (Error %s)"
IDS_HTTP_STATUS_OTHER "An error has occured during this request. Do you want to try the request again?"
// HTTP status code
IDS_HTTP_STATUS_REQUEST_TIMEOUT "The server used to download the requested components is not responding and the connection has timed out. Do you want to try to connect again?"
IDS_HTTP_STATUS_FORBIDDEN "You do not have permission to access the server to download the components requested by the application. Retry your access to the server?"
IDS_HTTP_STATUS_SERVER_ERROR "An error occured on the server and it could not complete the request. Do you want to try the request again?"
IDS_HTTP_STATUS_SERVICE_UNAVAIL "The requested service is temporarily unavailable. Do you want to try the request again?"
IDS_DOWNLOAD_STATUS_RETRY "Server is currently busy, retry in %ld seconds ..."
IDS_ERROR_CAPTION "Java Installer"
IDS_HOURSMINUTESECOND "Estimated time remaining: %d hours %d minutes %.0f seconds"
IDS_HOURMINUTESECOND "Estimated time remaining: %d hour %d minutes %.0f seconds"
IDS_MINUTESECOND "Estimated time remaining: %d minutes %.0f seconds"
IDS_SECOND "Estimated time remaining: %.0f seconds"
IDS_DISK_FULL_ERROR_CAPTION "Disk Full %s"
IDS_DISK_FULL_ERROR "There is not enough space on the disk to download the requested components. Clear space on the disk and then Retry."
IDS_DISK_WRITE_ERROR_CAPTION "Can't write to the disk %s"
IDS_DISK_WRITE_ERROR "An error occurred during writing to the disk. Please check that the disk is not write protected."
IDS_HTTP_STATUS_SERVER_NOT_REACHABLE "Java cannot connect to the Internet. Please check that the Internet Connection settings are correct (these can be found in the Windows Control Panel under Internet Options > Connection) and that your firewall allows java.exe to access the Internet."
IDS_DOWNLOAD_RETRY "Download error"
IDS_DOWNLOAD_RETRY_TEXT "An error occurred during the download of some requested components. Do you want to try the download of these components again?"
IDS_DOWNLOAD "Installing Additional Components"
IDS_DOWNLOAD_UNPACKING "Unpacking bundle"
IDS_DOWNLOAD_TEXT "The Java application will start when additional components that it requires are downloaded and installed."
IDS_FILE_UPDATE_ERROR "An error occurred while updating %s%s."
IDS_FILE_DELETE_ERROR "An error occurred while removing %s."
IDS_JAVA_HOME_ERROR "Unable to determine Java home directory."
IDS_KERNEL_HOME_ERROR "Unable to determine path to jkernel.dll."
IDS_JBROKER_ERROR "Unable to launch jbroker.exe."
IDS_FATAL_ERROR "Java was unable to download required components. The program will now exit."
IDS_ERROR_DOWNLOADING_BUNDLE_PROPERTIES "Java was unable to communicate with the download server. The program will now exit."
IDS_ERROR_MALFORMED_BUNDLE_PROPERTIES "Java encountered an error communicating with the download server. The program will now exit."
IDS_ERROR_MALFORMED_URL "Java was unable to download from the URL '%s'. The program will now exit."
END
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 340, 120
STYLE DS_MODALFRAME | DS_3DLOOK | DS_CENTER | WS_POPUP |
WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Componentes adicionales necesarios"
EXSTYLE WS_EX_APPWINDOW
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "", IDC_DOWNLOAD_MASTHEAD, 0, 0, 340, 39
LTEXT "", IDC_MASTHEAD_TEXT, 60, 8, 225, 20
CONTROL "", IDC_STATIC,"Static", SS_BLACKFRAME | SS_SUNKEN,
0, 39, 340, 1
LTEXT "", IDC_DOWNLOAD_TEXT, 12, 60, 316, 20
LTEXT "", IDC_TIME_REMAINING, 12, 90, 316, 10
CONTROL "Progress1",1006,"msctls_progress32",PBS_SMOOTH,
12, 100, 265, 14
PUSHBUTTON "Cancelar", 2, 285, 100, 46, 14
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
105, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 236
TOPMARGIN, 7
BOTTOMMARGIN, 63
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_DOWNLOAD_CANCEL_MESSAGE "Cancelar la instalación de los componentes adicionales que necesita la aplicación puede hacer que se cierre la aplicación.\n\n¿Seguro que desea cancelar la instalación de componentes adicionales?"
IDS_DOWNLOAD_CANCEL_CAPTION "Cancelar - Componentes adicionales"
IDS_DOWNLOAD_CANCEL_INSTRUCTION ""
IDS_HTTP_INSTRUCTION_REQUEST_TIMEOUT "Se ha agotado el tiempo de espera de la conexión"
IDS_HTTP_INSTRUCTION_SERVER_NOT_REACHABLE "No es posible conectarse a Internet"
IDS_HTTP_INSTRUCTION_UNKNOWN_ERROR "Ha habido un error en el servidor (error %s)"
IDS_HTTP_INSTRUCTION_SERVICE_UNAVAIL "El servicio no está disponible (error %s)"
IDS_HTTP_INSTRUCTION_FORBIDDEN "El acceso se ha denegado o está prohibido (error %s)"
IDS_HTTP_STATUS_OTHER "Ha habido un error en el transcurso de esta solicitud. ¿Desea ejecutar de nuevo la solicitud?"
// HTTP status code
IDS_HTTP_STATUS_REQUEST_TIMEOUT "El servidor ha agotado el tiempo de espera de la solicitud."
IDS_HTTP_STATUS_FORBIDDEN "El servidor ha podido interpretar la solicitud, pero la rechaza."
IDS_HTTP_STATUS_SERVER_ERROR "El servidor ha encontrado una condición inesperada que le ha impedido satisfacer la solicitud."
IDS_HTTP_STATUS_SERVICE_UNAVAIL "El servicio está temporalmente sobrecargado."
IDS_DOWNLOAD_STATUS_RETRY "El servidor está ocupado en este momento, se volverá a intentar la conexión en %ld segundos..."
IDS_ERROR_CAPTION "Error - Java Kernel"
IDS_HOURSMINUTESECOND "Tiempo restante estimado: %d horas %d minutos %.0f segundos"
IDS_HOURMINUTESECOND "Tiempo restante estimado: %d hora %d minutos %.0f segundos"
IDS_MINUTESECOND "Tiempo restante estimado: %d minutos %.0f segundos"
IDS_SECOND "Tiempo restante estimado: %.0f segundos"
IDS_DISK_FULL_ERROR_CAPTION "Disco lleno"
IDS_DISK_FULL_ERROR "Java Kernel no puede descargar los componentes necesarios porque el disco está lleno. ¿Desea volver a intentarlo?"
IDS_DISK_WRITE_ERROR_CAPTION "Error de escritura en disco"
IDS_DISK_WRITE_ERROR "Se ha producido un error cuando Java Kernel intentaba escribir en el disco. ¿Desea volver a intentarlo?"
IDS_HTTP_STATUS_SERVER_NOT_REACHABLE "Java Kernel no puede continuar con la configuración actual de conexión a Internet del sistema. En el Panel de control de Windows, compruebe Opciones de Internet -> Conexiones para verificar que la información de la configuración y de proxy sea la correcta."
IDS_DOWNLOAD_RETRY "Error de descarga"
IDS_DOWNLOAD_RETRY_TEXT "Se ha producido un error durante la descarga de algunos componentes solicitados. ¿Quiere volver a intentar descargar estos componentes?"
IDS_DOWNLOAD "Instalación de componentes adicionales"
IDS_DOWNLOAD_UNPACKING "Desempaquetando paquete"
IDS_DOWNLOAD_TEXT "La aplicación Java se iniciará cuando los componentes adicionales necesarios se hayan descargado e instalado."
IDS_FILE_UPDATE_ERROR "Se ha producido un error al actualizar %s%s."
IDS_FILE_DELETE_ERROR "Se ha producido un error al eliminar %s."
IDS_JAVA_HOME_ERROR "Imposible determinar el directorio de inicio Java."
IDS_KERNEL_HOME_ERROR "Imposible determinar la ruta a jkernel.dll."
IDS_JBROKER_ERROR "Imposible iniciar jbroker.exe."
IDS_FATAL_ERROR "Java no ha podido descargar los componentes necesarios. El programa se cerrará."
IDS_ERROR_DOWNLOADING_BUNDLE_PROPERTIES "Java no ha podido comunicarse con el servidor de descarga. El programa se cerrará."
IDS_ERROR_MALFORMED_BUNDLE_PROPERTIES "Se ha producido un error en la comunicación entre Java y el servidor de descarga. El programa se cerrará."
IDS_ERROR_MALFORMED_URL "Java no ha podido realizar la descarga desde el URL '%s'. El programa se cerrará."
END
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 340, 120
STYLE DS_MODALFRAME | DS_3DLOOK | DS_CENTER | WS_POPUP |
WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Composants supplémentaires requis"
EXSTYLE WS_EX_APPWINDOW
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "", IDC_DOWNLOAD_MASTHEAD, 0, 0, 340, 39
LTEXT "", IDC_MASTHEAD_TEXT, 60, 4, 220, 30
CONTROL "", IDC_STATIC,"Static", SS_BLACKFRAME | SS_SUNKEN,
0, 39, 340, 1
LTEXT "", IDC_DOWNLOAD_TEXT, 12, 60, 316, 20
LTEXT "", IDC_TIME_REMAINING, 12, 90, 316, 10
CONTROL "Progress1",1006,"msctls_progress32",PBS_SMOOTH,
12, 100, 265, 14
PUSHBUTTON "Annuler", 2, 285, 100, 46, 14
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
105, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 236
TOPMARGIN, 7
BOTTOMMARGIN, 63
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_DOWNLOAD_CANCEL_MESSAGE "L'annulation de l'installation de composants supplémentaires nécessaires à l'application risque d'entraîner la fermeture de celle-ci.\n\nVoulez-vous vraiment annuler l'installation des composants supplémentaires ?"
IDS_DOWNLOAD_CANCEL_CAPTION "Annuler : composants supplémentaires"
IDS_DOWNLOAD_CANCEL_INSTRUCTION ""
IDS_HTTP_INSTRUCTION_REQUEST_TIMEOUT "Délai de connexion dépassé"
IDS_HTTP_INSTRUCTION_SERVER_NOT_REACHABLE "Connexion à Internet impossible"
IDS_HTTP_INSTRUCTION_UNKNOWN_ERROR "Erreur de serveur (erreur %s)"
IDS_HTTP_INSTRUCTION_SERVICE_UNAVAIL "Service non disponible (erreur %s)"
IDS_HTTP_INSTRUCTION_FORBIDDEN "Accès refusé ou interdit (erreur %s)"
IDS_HTTP_STATUS_OTHER "Une erreur s'est produite lors de cette demande. Voulez-vous effectuer à nouveau la demande ?"
// HTTP status code
IDS_HTTP_STATUS_REQUEST_TIMEOUT "Temporisation du serveur lors de l'attente de la requête."
IDS_HTTP_STATUS_FORBIDDEN "Le serveur a compris la requête mais refuse de la satisfaire."
IDS_HTTP_STATUS_SERVER_ERROR "Le serveur a rencontré une condition inattendue l'empêchant de satisfaire la requête."
IDS_HTTP_STATUS_SERVICE_UNAVAIL "Le service est temporairement surchargé."
IDS_DOWNLOAD_STATUS_RETRY "Le serveur est occupé ; veuillez réessayer dans %ld secondes..."
IDS_ERROR_CAPTION "Erreur - Java Kernel"
IDS_HOURSMINUTESECOND "Temps restant prévu : %d heures %d minutes %.0f secondes"
IDS_HOURMINUTESECOND "Temps restant prévu : %d heure %d minutes %.0f secondes"
IDS_MINUTESECOND "Temps restant prévu : %d minutes %.0f secondes"
IDS_SECOND "Temps restant prévu : %.0f secondes"
IDS_DISK_FULL_ERROR_CAPTION "Disque saturé"
IDS_DISK_FULL_ERROR "En raison de la saturation du disque, Java Kernel n'a pas été en mesure de télécharger les composants requis. Voulez-vous réessayer ?"
IDS_DISK_WRITE_ERROR_CAPTION "Erreur d'écriture sur le disque"
IDS_DISK_WRITE_ERROR "Java Kernel a rencontré une erreur lors de l'écriture sur le disque. Voulez-vous réessayer ?"
IDS_HTTP_STATUS_SERVER_NOT_REACHABLE "Java Kernel ne peut pas s'exécuter avec les paramètres de connexion Internet actuels de votre système. Dans le Panneau de configuration de Windows, cliquez sur Options Internet -> Connexions pour vérifier les paramètres et informations de proxy."
IDS_DOWNLOAD_RETRY "Erreur de téléchargement"
IDS_DOWNLOAD_RETRY_TEXT "Une erreur s'est produite lors du téléchargement de certains composants requis. Souhaitez-vous réessayer de télécharger ces composants ?"
IDS_DOWNLOAD "Installation de composants supplémentaires"
IDS_DOWNLOAD_UNPACKING "Décompression du bundle"
IDS_DOWNLOAD_TEXT "L'application Java démarre lorsque des composants supplémentaires requis sont téléchargés et installés."
IDS_FILE_UPDATE_ERROR "Une erreur s'est produite lors de la mise à jour de %s%s."
IDS_FILE_DELETE_ERROR "Une erreur s'est produite lors de la suppression de %s."
IDS_JAVA_HOME_ERROR "Le répertoire d'accueil Java est introuvable."
IDS_KERNEL_HOME_ERROR "Le chemin de jkernel.dll est introuvable."
IDS_JBROKER_ERROR "Impossible de lancer jbroker.exe."
IDS_FATAL_ERROR "Java n'a pas été en mesure de télécharger les composants requis. Fermeture imminente du programme."
IDS_ERROR_DOWNLOADING_BUNDLE_PROPERTIES "Java n'a pas été en mesure de communiquer avec le serveur de téléchargement. Fermeture imminente du programme."
IDS_ERROR_MALFORMED_BUNDLE_PROPERTIES "Java a rencontré une erreur lors de la communication avec le serveur de téléchargement. Fermeture imminente du programme."
IDS_ERROR_MALFORMED_URL "Java n'a pas été en mesure de réaliser le téléchargement à partir de l'URL '%s'. Fermeture imminente du programme."
END
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 340, 120
STYLE DS_MODALFRAME | DS_3DLOOK | DS_CENTER | WS_POPUP |
WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Componenti aggiuntivi richiesti"
EXSTYLE WS_EX_APPWINDOW
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "", IDC_DOWNLOAD_MASTHEAD, 0, 0, 340, 39
LTEXT "", IDC_MASTHEAD_TEXT, 60, 4, 220, 30
CONTROL "", IDC_STATIC,"Static", SS_BLACKFRAME | SS_SUNKEN,
0, 39, 340, 1
LTEXT "", IDC_DOWNLOAD_TEXT, 12, 60, 316, 20
LTEXT "", IDC_TIME_REMAINING, 12, 90, 316, 10
CONTROL "Progress1",1006,"msctls_progress32",PBS_SMOOTH,
12, 100, 265, 14
PUSHBUTTON "Annulla", 2, 285, 100, 46, 14
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
105, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 236
TOPMARGIN, 7
BOTTOMMARGIN, 63
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_DOWNLOAD_CANCEL_MESSAGE "Se si annulla l'installazione di componenti aggiuntivi necessari per l'applicazione, quest'ultima potrebbe chiudersi.\n\nAnnullare l'installazione di componenti aggiuntivi?"
IDS_DOWNLOAD_CANCEL_CAPTION "Annulla - Componenti aggiuntivi"
IDS_DOWNLOAD_CANCEL_INSTRUCTION ""
IDS_HTTP_INSTRUCTION_REQUEST_TIMEOUT "Timeout della connessione"
IDS_HTTP_INSTRUCTION_SERVER_NOT_REACHABLE "Impossibile stabilire una connessione a Internet"
IDS_HTTP_INSTRUCTION_UNKNOWN_ERROR "Errore del server (errore %s)"
IDS_HTTP_INSTRUCTION_SERVICE_UNAVAIL "Servizio non disponibile (errore %s)"
IDS_HTTP_INSTRUCTION_FORBIDDEN "Accesso negato o vietato (errore %s)"
IDS_HTTP_STATUS_OTHER "Errore durante la richiesta. Provare a reinviare la richiesta?"
// HTTP status code
IDS_HTTP_STATUS_REQUEST_TIMEOUT "Tempo scaduto del server in attesa della richiesta."
IDS_HTTP_STATUS_FORBIDDEN "Il server ha ricevuto la richiesta ma non ne consente l'elaborazione."
IDS_HTTP_STATUS_SERVER_ERROR "Il server ha rilevato una condizione imprevista che ha impedito di soddisfare la richiesta."
IDS_HTTP_STATUS_SERVICE_UNAVAIL "Il servizio è temporaneamente sovraccarico."
IDS_DOWNLOAD_STATUS_RETRY "Server occupato, riprovare tra %ld secondi..."
IDS_ERROR_CAPTION "Errore - Java Kernel"
IDS_HOURSMINUTESECOND "Tempo rimanente previsto: %d ore %d minuti %.0f secondi"
IDS_HOURMINUTESECOND "Tempo rimanente previsto: %d ora %d minuti %.0f secondi"
IDS_MINUTESECOND "Tempo rimanente previsto: %d minuti %.0f secondi"
IDS_SECOND "Tempo rimanente previsto: %.0f secondi"
IDS_DISK_FULL_ERROR_CAPTION "Disco pieno"
IDS_DISK_FULL_ERROR "Java Kernel non ha effettuato il download dei componenti necessari perché il disco è pieno. Riprovare?"
IDS_DISK_WRITE_ERROR_CAPTION "Errore di scrittura sul disco"
IDS_DISK_WRITE_ERROR "Java Kernel ha rilevato un errore durante la scrittura sul disco. Riprovare?"
IDS_HTTP_STATUS_SERVER_NOT_REACHABLE "Non è possibile utilizzare Java Kernel con le impostazioni di connessione Internet attive nel sistema. Nel Pannello di controllo di Windows, selezionare Opzioni Internet -> Connessioni per controllare che le impostazioni e le informazioni sul proxy siano corrette."
IDS_DOWNLOAD_RETRY "Errore di download"
IDS_DOWNLOAD_RETRY_TEXT "Si è verificato un errore durante il download di alcuni componenti richiesti. Ritentare il download di tali componenti?"
IDS_DOWNLOAD "Installazione di componenti aggiuntivi in corso"
IDS_DOWNLOAD_UNPACKING "Decompressione del bundle in corso"
IDS_DOWNLOAD_TEXT "L'applicazione Java verrà avviata dopo il download e l'installazione dei componenti richiesti."
IDS_FILE_UPDATE_ERROR "Errore durante l'aggiornamento di %s%s."
IDS_FILE_DELETE_ERROR "Errore durante la rimozione di %s."
IDS_JAVA_HOME_ERROR "Impossibile determinare la directory home di Java."
IDS_KERNEL_HOME_ERROR "Impossibile determinare il percorso di jkernel.dll."
IDS_JBROKER_ERROR "Impossibile avviare jbroker.exe."
IDS_FATAL_ERROR "Java non è in grado di scaricare i componenti necessari. Il programma verrà terminato."
IDS_ERROR_DOWNLOADING_BUNDLE_PROPERTIES "Java non è in grado di comunicare con il server di download. Il programma verrà terminato."
IDS_ERROR_MALFORMED_BUNDLE_PROPERTIES "Java ha rilevato un errore durante la comunicazione con il server di download. Il programma verrà terminato."
IDS_ERROR_MALFORMED_URL "Java non è in grado di eseguire il download dall'URL '%s'. Il programma verrà terminato."
END
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 340, 120
STYLE DS_MODALFRAME | DS_3DLOOK | DS_CENTER | WS_POPUP |
WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "追加コンポーネントが必要"
EXSTYLE WS_EX_APPWINDOW
FONT 10, "MS UI Gothic"
BEGIN
LTEXT "", IDC_DOWNLOAD_MASTHEAD, 0, 0, 340, 39
LTEXT "", IDC_MASTHEAD_TEXT, 60, 14, 200, 12
CONTROL "", IDC_STATIC,"Static", SS_BLACKFRAME | SS_SUNKEN,
0, 39, 340, 1
LTEXT "", IDC_DOWNLOAD_TEXT, 12, 60, 316, 20
LTEXT "", IDC_TIME_REMAINING, 12, 90, 316, 10
CONTROL "Progress1",1006,"msctls_progress32",PBS_SMOOTH,
12, 100, 265, 14
PUSHBUTTON "取消し", 2, 285, 100, 46, 14
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
105, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 236
TOPMARGIN, 7
BOTTOMMARGIN, 63
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_DOWNLOAD_CANCEL_MESSAGE "アプリケーションが必要とする追加コンポーネントのインストールをキャンセルすると、アプリケーションが終了する可能性があります。\n\n追加コンポーネントのインストールをキャンセルしてよろしいですか?"
IDS_DOWNLOAD_CANCEL_CAPTION "キャンセル - 追加コンポーネント"
IDS_DOWNLOAD_CANCEL_INSTRUCTION ""
IDS_HTTP_INSTRUCTION_REQUEST_TIMEOUT "接続がタイムアウトしました"
IDS_HTTP_INSTRUCTION_SERVER_NOT_REACHABLE "インターネットに接続できません"
IDS_HTTP_INSTRUCTION_UNKNOWN_ERROR "サーバーエラー (エラー %s)"
IDS_HTTP_INSTRUCTION_SERVICE_UNAVAIL "サービス利用不可 (エラー %s)"
IDS_HTTP_INSTRUCTION_FORBIDDEN "アクセスが拒否または禁止されています (エラー %s)"
IDS_HTTP_STATUS_OTHER "この要求の処理中にエラーが発生しました。要求を再試行しますか?"
// HTTP status code
IDS_HTTP_STATUS_REQUEST_TIMEOUT "要求を待機中にサーバーがタイムアウトしました。"
IDS_HTTP_STATUS_FORBIDDEN "サーバーは、要求を認識していますが、実行を拒否しています。"
IDS_HTTP_STATUS_SERVER_ERROR "サーバーは、要求の実行を妨げる予期しない状況に遭遇しました。"
IDS_HTTP_STATUS_SERVICE_UNAVAIL "サービスが一時的にオーバーロードしています。"
IDS_DOWNLOAD_STATUS_RETRY "サーバーは現在ビジーです。%ld 秒後に再試行します ..."
IDS_ERROR_CAPTION "エラー - Java カーネル"
IDS_HOURSMINUTESECOND "予想残り時間: %d 時間 %d 分 %.0f 秒"
IDS_HOURMINUTESECOND "予想残り時間: %d 時間 %d 分 %.0f 秒"
IDS_MINUTESECOND "予想残り時間: %d 分 %.0f 秒"
IDS_SECOND "予想残り時間: %.0f 秒"
IDS_DISK_FULL_ERROR_CAPTION "ディスクがいっぱいです"
IDS_DISK_FULL_ERROR "ディスクがいっぱいのため、Java カーネルが必要なコンポーネントをダウンロードできませんでした。もう一度試しますか?"
IDS_DISK_WRITE_ERROR_CAPTION "ディスク書き込みエラー"
IDS_DISK_WRITE_ERROR "Java カーネルがディスクへの書き込み時にエラーを検出しました。もう一度試しますか?"
IDS_HTTP_STATUS_SERVER_NOT_REACHABLE "Java カーネルは、お使いのシステムの現在のインターネット接続設定では動作しません。Windows のコントロールパネルで、「インターネットオプション」 -> 「接続」を選択して、設定およびプロキシ情報が正しいことを確認してください。"
IDS_DOWNLOAD_RETRY "ダウンロードエラー"
IDS_DOWNLOAD_RETRY_TEXT "要求されたコンポーネントの一部をダウンロード中にエラーが発生しました。これらのコンポーネントのダウンロードを再度試みますか ?"
IDS_DOWNLOAD "追加コンポーネントをインストールしています"
IDS_DOWNLOAD_UNPACKING "バンドルを展開しています"
IDS_DOWNLOAD_TEXT "Java アプリケーションは、必須の追加コンポーネントのダウンロードおよびインストール後に起動します。"
IDS_FILE_UPDATE_ERROR "%s%s の更新中にエラーが発生しました。"
IDS_FILE_DELETE_ERROR "%s の削除中にエラーが発生しました。"
IDS_JAVA_HOME_ERROR "Java ホームディレクトリを判定できません。"
IDS_KERNEL_HOME_ERROR "jkernel.dll のパスを判定できません。"
IDS_JBROKER_ERROR "jbroker.exe を起動できません。"
IDS_FATAL_ERROR "Java が必要なコンポーネントをダウンロードできませんでした。プログラムは終了します。"
IDS_ERROR_DOWNLOADING_BUNDLE_PROPERTIES "Java がダウンロードサーバーと通信できませんでした。プログラムは終了します。"
IDS_ERROR_MALFORMED_BUNDLE_PROPERTIES "Java がダウンロードサーバーとの通信中にエラーを検出しました。プログラムは終了します。"
IDS_ERROR_MALFORMED_URL "Java が URL '%s' からダウンロードできませんでした。プログラムは終了します。"
END
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 340, 120
STYLE DS_MODALFRAME | DS_3DLOOK | DS_CENTER | WS_POPUP |
WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "추가 구성 요소 필요"
EXSTYLE WS_EX_APPWINDOW
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "", IDC_DOWNLOAD_MASTHEAD, 0, 0, 340, 39
LTEXT "", IDC_MASTHEAD_TEXT, 60, 14, 200, 12
CONTROL "", IDC_STATIC,"Static", SS_BLACKFRAME | SS_SUNKEN,
0, 39, 340, 1
LTEXT "", IDC_DOWNLOAD_TEXT, 12, 60, 316, 20
LTEXT "", IDC_TIME_REMAINING, 12, 90, 316, 10
CONTROL "Progress1",1006,"msctls_progress32",PBS_SMOOTH,
12, 100, 265, 14
PUSHBUTTON "취소", 2, 285, 100, 46, 14
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
105, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 236
TOPMARGIN, 7
BOTTOMMARGIN, 63
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_DOWNLOAD_CANCEL_MESSAGE "응용 프로그램에서 필요한 추가 구성 요소의 설치를 취소하면 응용 프로그램이 종료될 수 있습니다.\n\n추가 구성 요소의 설치를 취소하시겠습니까?"
IDS_DOWNLOAD_CANCEL_CAPTION "취소 - 추가 구성 요소"
IDS_DOWNLOAD_CANCEL_INSTRUCTION ""
IDS_HTTP_INSTRUCTION_REQUEST_TIMEOUT "연결 시간 초과"
IDS_HTTP_INSTRUCTION_SERVER_NOT_REACHABLE "인터넷에 연결할 수 없습니다."
IDS_HTTP_INSTRUCTION_UNKNOWN_ERROR "서버 오류(오류 %s)"
IDS_HTTP_INSTRUCTION_SERVICE_UNAVAIL "서비스를 사용할 수 없음(오류 %s)"
IDS_HTTP_INSTRUCTION_FORBIDDEN "액세스가 거부되었거나 금지됨(오류 %s)"
IDS_HTTP_STATUS_OTHER "이 요청 동안 오류가 발생했습니다. 요청을 다시 시도하시겠습니까?"
// HTTP status code
IDS_HTTP_STATUS_REQUEST_TIMEOUT "서버가 요청을 기다리는 동안 시간이 초과되었습니다."
IDS_HTTP_STATUS_FORBIDDEN "서버가 요청을 이해했지만 이행하기를 거부합니다."
IDS_HTTP_STATUS_SERVER_ERROR "서버에서 요청 이행을 방해하는 예상치 못한 조건이 발견되었습니다."
IDS_HTTP_STATUS_SERVICE_UNAVAIL "서버가 일시적으로 과부하되었습니다."
IDS_DOWNLOAD_STATUS_RETRY "현재 서버가 사용 중이므로 %ld초 후에 다시 시도하십시오."
IDS_ERROR_CAPTION "오류 - Java 커널"
IDS_HOURSMINUTESECOND "예상된 남은 시간: %d시간 %d분 %.0f초"
IDS_HOURMINUTESECOND "예상된 남은 시간: %d시간 %d분 %.0f초"
IDS_MINUTESECOND "예상된 남은 시간: %d분 %.0f초"
IDS_SECOND "예상된 남은 시간: %.0f초"
IDS_DISK_FULL_ERROR_CAPTION "디스크가 가득 참"
IDS_DISK_FULL_ERROR "디스크가 가득 차서 Java Kernel에서 필요한 구성 요소를 다운로드하지 못했습니다. 다시 시도하시겠습니까?"
IDS_DISK_WRITE_ERROR_CAPTION "디스크 쓰기 오류"
IDS_DISK_WRITE_ERROR "디스크에 쓰는 동안 Java Kernel에서 오류가 발생했습니다. 다시 시도하시겠습니까?"
IDS_HTTP_STATUS_SERVER_NOT_REACHABLE "시스템의 현재 인터넷 연결 설정으로는 Java Kernel을 계속할 수 없습니다. Windows 제어판에서 인터넷 옵션 -> 연결을 선택하여 설정 및 프록시 정보가 올바른지 확인하십시오."
IDS_DOWNLOAD_RETRY "다운로드 오류"
IDS_DOWNLOAD_RETRY_TEXT "요청된 구성 요소를 다운로드하는 동안 오류가 발생했습니다. 이 구성 요소를 다시 다운로드하시겠습니까?"
IDS_DOWNLOAD "추가 구성 요소 설치"
IDS_DOWNLOAD_UNPACKING "번들 압축 풀기"
IDS_DOWNLOAD_TEXT "필요한 추가 구성 요소가 다운로드되어 설치되면 Java 응용 프로그램이 시작됩니다."
IDS_FILE_UPDATE_ERROR "%s%s을(를) 업데이트하는 동안 오류가 발생했습니다."
IDS_FILE_DELETE_ERROR "%s을(를) 제거하는 동안 오류가 발생했습니다."
IDS_JAVA_HOME_ERROR "Java 홈 디렉토리를 확인할 수 없습니다."
IDS_KERNEL_HOME_ERROR "jkernel.dll의 경로를 확인할 수 없습니다."
IDS_JBROKER_ERROR "jbroker.exe를 시작할 수 없습니다."
IDS_FATAL_ERROR "필요한 구성 요소를 다운로드하지 못했습니다. 프로그램이 종료됩니다."
IDS_ERROR_DOWNLOADING_BUNDLE_PROPERTIES "다운로드 서버와 통신하지 못했습니다. 프로그램이 종료됩니다."
IDS_ERROR_MALFORMED_BUNDLE_PROPERTIES "다운로드 서버와의 통신 오류가 발생했습니다. 프로그램이 종료됩니다."
IDS_ERROR_MALFORMED_URL "URL '%s'에서 다운로드하지 못했습니다. 프로그램이 종료됩니다."
END
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 340, 120
STYLE DS_MODALFRAME | DS_3DLOOK | DS_CENTER | WS_POPUP |
WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Ytterligare komponenter behvs"
EXSTYLE WS_EX_APPWINDOW
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "", IDC_DOWNLOAD_MASTHEAD, 0, 0, 340, 39
LTEXT "", IDC_MASTHEAD_TEXT, 60, 14, 200, 12
CONTROL "", IDC_STATIC,"Static", SS_BLACKFRAME | SS_SUNKEN,
0, 39, 340, 1
LTEXT "", IDC_DOWNLOAD_TEXT, 12, 60, 316, 20
LTEXT "", IDC_TIME_REMAINING, 12, 90, 316, 10
CONTROL "Progress1",1006,"msctls_progress32",PBS_SMOOTH,
12, 100, 265, 14
PUSHBUTTON "Avbryt", 2, 285, 100, 46, 14
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
105, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 236
TOPMARGIN, 7
BOTTOMMARGIN, 63
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_DOWNLOAD_CANCEL_MESSAGE "Programmet kan avslutas om du avbryter installationen av ytterligare komponenter som r ndvndiga fr programmet.\n\nVill du avbryta installationen av ytterligare komponenter?"
IDS_DOWNLOAD_CANCEL_CAPTION "Avbryt - Ytterligare komponenter"
IDS_DOWNLOAD_CANCEL_INSTRUCTION ""
IDS_HTTP_INSTRUCTION_REQUEST_TIMEOUT "Anslutningen avbrts p grund av timeout"
IDS_HTTP_INSTRUCTION_SERVER_NOT_REACHABLE "Det gr inte att ansluta till Internet."
IDS_HTTP_INSTRUCTION_UNKNOWN_ERROR "Serverfel (Fel %s)"
IDS_HTTP_INSTRUCTION_SERVICE_UNAVAIL "Tjnsten r inte tillgnglig (Fel %s)"
IDS_HTTP_INSTRUCTION_FORBIDDEN "tkomst nekad eller frbjuden (Fel %s)"
IDS_HTTP_STATUS_OTHER "Ett fel intrffade i samband med begran. Vill du frska skicka begran igen?"
// HTTP status code
IDS_HTTP_STATUS_REQUEST_TIMEOUT "Ett tidsfel intrffade medan servern vntade p begran."
IDS_HTTP_STATUS_FORBIDDEN "Servern frstod begran men vgrar uppfylla den."
IDS_HTTP_STATUS_SERVER_ERROR "Ett ovntat tillstnd som innebr att begran inte kan uppfyllas ptrffades."
IDS_HTTP_STATUS_SERVICE_UNAVAIL "Tjnsten r tillflligt verbelastad."
IDS_DOWNLOAD_STATUS_RETRY "Servern r upptagen fr nrvarande. Frsk igen om %ld sekund(er) ..."
IDS_ERROR_CAPTION "Fel - Java Kernel"
IDS_HOURSMINUTESECOND "terstende tid: %d timmar %d minuter %.0f sekunder"
IDS_HOURMINUTESECOND "terstende tid: %d timme %d minuter %.0f sekunder"
IDS_MINUTESECOND "terstende tid: %d minuter %.0f sekunder"
IDS_SECOND "terstende tid: %.0f sekunder"
IDS_DISK_FULL_ERROR_CAPTION "Disken r full"
IDS_DISK_FULL_ERROR "Java Kernel kunde inte ladda ned ndvndiga komponenter drfr att disken r full. Frska igen?"
IDS_DISK_WRITE_ERROR_CAPTION "Fel vid skrivning till disk"
IDS_DISK_WRITE_ERROR "Java Kernel sttte p ett fel vid skrivning till disken. Frska igen?"
IDS_HTTP_STATUS_SERVER_NOT_REACHABLE "Java Kernel kan inte fortstta med systemets aktuella instllningar fr Internetanslutning. ppna Kontrollpanelen, Internet-alternativ > Anslutningar och kontrollera att instllningarna och proxyinformationen stmmer."
IDS_DOWNLOAD_RETRY "Nedladdningsfel"
IDS_DOWNLOAD_RETRY_TEXT "Ett fel uppstod under nedladdning av vissa begrda komponenter. Vill du frska ladda ned dessa komponenter igen?"
IDS_DOWNLOAD "Ytterligare komponenter installeras"
IDS_DOWNLOAD_UNPACKING "Uppackning av paket"
IDS_DOWNLOAD_TEXT "Java-applikationen startar nr ytterligare komponenter som krvs r nedladdade och installerade."
IDS_FILE_UPDATE_ERROR "Ett fel uppstod nr %s%s uppdaterades."
IDS_FILE_DELETE_ERROR "Ett fel uppstod nr %s skulle tas bort."
IDS_JAVA_HOME_ERROR "Det gr inte att avgra Javas hemkatalog"
IDS_KERNEL_HOME_ERROR "Det gr inte att avgra skvgen till jkernell.dll."
IDS_JBROKER_ERROR "Det gr inte att starta jbroker.exe."
IDS_FATAL_ERROR "Det gick inte att ladda ned de ndvndiga komponenterna med Java. Programmet avslutas."
IDS_ERROR_DOWNLOADING_BUNDLE_PROPERTIES "Det gick inte att upprtta ngon kommunikation mellan Java och nedladdningsservern. Programmet avslutas."
IDS_ERROR_MALFORMED_BUNDLE_PROPERTIES "Det uppstod ett fel i kommunikationen mellan Java och nedladdningsservern. Programmet avslutas."
IDS_ERROR_MALFORMED_URL "Det gick inte att ladda ned frn webbadressen '%s'. Programmet avslutas."
END
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 340, 120
STYLE DS_MODALFRAME | DS_3DLOOK | DS_CENTER | WS_POPUP |
WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "所需的其他组件"
EXSTYLE WS_EX_APPWINDOW
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "", IDC_DOWNLOAD_MASTHEAD, 0, 0, 340, 39
LTEXT "", IDC_MASTHEAD_TEXT, 60, 14, 200, 12
CONTROL "", IDC_STATIC,"Static", SS_BLACKFRAME | SS_SUNKEN,
0, 39, 340, 1
LTEXT "", IDC_DOWNLOAD_TEXT, 12, 60, 316, 20
LTEXT "", IDC_TIME_REMAINING, 12, 90, 316, 10
CONTROL "Progress1",1006,"msctls_progress32",PBS_SMOOTH,
12, 100, 265, 14
PUSHBUTTON "取消", 2, 285, 100, 46, 14
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
105, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 236
TOPMARGIN, 7
BOTTOMMARGIN, 63
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_DOWNLOAD_CANCEL_MESSAGE "取消安装应用程序所需的额外组件可能会导致该应用程序退出。\n\n是否确定要取消安装额外组件?"
IDS_DOWNLOAD_CANCEL_CAPTION "取消 - 额外组件"
IDS_DOWNLOAD_CANCEL_INSTRUCTION ""
IDS_HTTP_INSTRUCTION_REQUEST_TIMEOUT "连接已超时"
IDS_HTTP_INSTRUCTION_SERVER_NOT_REACHABLE "无法连接到 Internet"
IDS_HTTP_INSTRUCTION_UNKNOWN_ERROR "服务器错误(错误 %s)"
IDS_HTTP_INSTRUCTION_SERVICE_UNAVAIL "服务不可用(错误 %s)"
IDS_HTTP_INSTRUCTION_FORBIDDEN "拒绝访问或禁止访问(错误 %s)"
IDS_HTTP_STATUS_OTHER "在此请求期间出现错误。您是否要重试请求?"
// HTTP status code
IDS_HTTP_STATUS_REQUEST_TIMEOUT "服务器等待请求时超时。"
IDS_HTTP_STATUS_FORBIDDEN "服务器已接受请求,但拒绝执行。"
IDS_HTTP_STATUS_SERVER_ERROR "服务器遇到意外情况,无法完成请求。"
IDS_HTTP_STATUS_SERVICE_UNAVAIL "服务暂时过载。"
IDS_DOWNLOAD_STATUS_RETRY "服务器正忙,请在 %ld 秒后重试..."
IDS_ERROR_CAPTION "错误 - Java Kernel"
IDS_HOURSMINUTESECOND "估计剩余时间:%d 小时 %d 分钟 %.0f 秒"
IDS_HOURMINUTESECOND "估计剩余时间:%d 小时 %d 分钟 %.0f 秒"
IDS_MINUTESECOND "估计剩余时间:%d 分钟 %.0f 秒"
IDS_SECOND "估计剩余时间:%.0f 秒"
IDS_DISK_FULL_ERROR_CAPTION "磁盘已满"
IDS_DISK_FULL_ERROR "由于磁盘已满,Java Kernel 无法下载所需的组件。是否重试?"
IDS_DISK_WRITE_ERROR_CAPTION "磁盘写入错误"
IDS_DISK_WRITE_ERROR "在向磁盘执行写入操作时 Java Kernel 遇到错误。是否重试?"
IDS_HTTP_STATUS_SERVER_NOT_REACHABLE "在使用系统当前的 Internet 连接设置的情况下,Java Kernel 无法继续执行。在 Windows""控制面板""中,请检查""Internet 选项""->""连接""以确保设置和代理信息正确。"
IDS_DOWNLOAD_RETRY "下载错误"
IDS_DOWNLOAD_RETRY_TEXT "在下载某些请求的组件期间发生错误。是否要再试一次下载这些组件?"
IDS_DOWNLOAD "安装其他组件"
IDS_DOWNLOAD_UNPACKING "正在解压缩包"
IDS_DOWNLOAD_TEXT "下载并安装 Java 应用程序所需的其他组件后,该应用程序将启动。"
IDS_FILE_UPDATE_ERROR "更新 %s%s 时发生错误。"
IDS_FILE_DELETE_ERROR "删除 %s 时发生错误。"
IDS_JAVA_HOME_ERROR "无法确定 Java 主目录。"
IDS_KERNEL_HOME_ERROR "无法确定 jkernel.dll 的路径。"
IDS_JBROKER_ERROR "无法启动 jbroker.exe。"
IDS_FATAL_ERROR "Java 无法下载所需的组件。现在程序将退出。"
IDS_ERROR_DOWNLOADING_BUNDLE_PROPERTIES "Java 无法与下载服务器进行通信。现在程序将退出。"
IDS_ERROR_MALFORMED_BUNDLE_PROPERTIES "Java 在与下载服务器进行通信时遇到错误。现在程序将退出。"
IDS_ERROR_MALFORMED_URL "Java 无法从 URL '%s' 执行下载。现在程序将退出。"
END
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DOWNLOAD_DIALOG DIALOGEX 0, 0, 340, 120
STYLE DS_MODALFRAME | DS_3DLOOK | DS_CENTER | WS_POPUP |
WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "所需的其他元件"
EXSTYLE WS_EX_APPWINDOW
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "", IDC_DOWNLOAD_MASTHEAD, 0, 0, 340, 39
LTEXT "", IDC_MASTHEAD_TEXT, 60, 14, 200, 12
CONTROL "", IDC_STATIC,"Static", SS_BLACKFRAME | SS_SUNKEN,
0, 39, 340, 1
LTEXT "", IDC_DOWNLOAD_TEXT, 12, 60, 316, 20
LTEXT "", IDC_TIME_REMAINING, 12, 90, 316, 10
CONTROL "Progress1",1006,"msctls_progress32",PBS_SMOOTH,
12, 100, 265, 14
PUSHBUTTON "取消", 2, 285, 100, 46, 14
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
105, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 236
TOPMARGIN, 7
BOTTOMMARGIN, 63
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_DOWNLOAD_CANCEL_MESSAGE "取消安裝應用程式所需的其他元件,可能會導致應用程式結束。\n\n您確定要取消安裝其他元件?"
IDS_DOWNLOAD_CANCEL_CAPTION "取消 - 其他元件"
IDS_DOWNLOAD_CANCEL_INSTRUCTION ""
IDS_HTTP_INSTRUCTION_REQUEST_TIMEOUT "連線逾時"
IDS_HTTP_INSTRUCTION_SERVER_NOT_REACHABLE "無法連線至網際網路"
IDS_HTTP_INSTRUCTION_UNKNOWN_ERROR "伺服器錯誤 (錯誤 %s)"
IDS_HTTP_INSTRUCTION_SERVICE_UNAVAIL "無法使用服務 (錯誤 %s)"
IDS_HTTP_INSTRUCTION_FORBIDDEN "拒絕或禁止存取 (錯誤 %s)"
IDS_HTTP_STATUS_OTHER "在此請求期間發生錯誤。是否要重試請求?"
// HTTP status code
IDS_HTTP_STATUS_REQUEST_TIMEOUT "伺服器等待請求時出現逾時。"
IDS_HTTP_STATUS_FORBIDDEN "伺服器瞭解該請求,但正在拒絕實現它。"
IDS_HTTP_STATUS_SERVER_ERROR "伺服器遇到阻止其實現請求的未預期條件。"
IDS_HTTP_STATUS_SERVICE_UNAVAIL "服務暫時超載。"
IDS_DOWNLOAD_STATUS_RETRY "伺服器目前處於忙碌狀態,請在 %ld 秒後重試..."
IDS_ERROR_CAPTION "錯誤 - Java Kernel"
IDS_HOURSMINUTESECOND "預估剩餘時間:%d 小時 %d 分 %.0f 秒"
IDS_HOURMINUTESECOND "預估剩餘時間:%d 小時 %d 分 %.0f 秒"
IDS_MINUTESECOND "預估剩餘時間:%d 分 %.0f 秒"
IDS_SECOND "預估剩餘時間:%.0f 秒"
IDS_DISK_FULL_ERROR_CAPTION "磁碟已滿"
IDS_DISK_FULL_ERROR "由於磁碟已滿,Java Kernel 無法下載所需的元件。是否要重試?"
IDS_DISK_WRITE_ERROR_CAPTION "磁碟寫入錯誤"
IDS_DISK_WRITE_ERROR "Java Kernel 在寫入至磁碟時遇到錯誤。是否要重試?"
IDS_HTTP_STATUS_SERVER_NOT_REACHABLE "在系統目前的網際網路連線設定下,Java Kernel 無法繼續執行。在 Windows「控制台」中,請核對「網際網路選項」->「連線」,以確定設定和代理伺服器資訊正確。"
IDS_DOWNLOAD_RETRY "下載錯誤"
IDS_DOWNLOAD_RETRY_TEXT "下載某些所需元件時發生錯誤。是否要重試下載這些元件?"
IDS_DOWNLOAD "正在安裝其他元件"
IDS_DOWNLOAD_UNPACKING "正在解壓縮束"
IDS_DOWNLOAD_TEXT "下載並安裝其他所需元件後,Java 應用程式將啟動。"
IDS_FILE_UPDATE_ERROR "更新 %s%s 時發生錯誤。"
IDS_FILE_DELETE_ERROR "移除 %s 時發生錯誤。"
IDS_JAVA_HOME_ERROR "無法確定 Java 主目錄。"
IDS_KERNEL_HOME_ERROR "無法確定 jkernel.dll 的路徑。"
IDS_JBROKER_ERROR "無法啟動 jbroker.exe。"
IDS_FATAL_ERROR "Java 無法下載所需的元件。程式將立即結束。"
IDS_ERROR_DOWNLOADING_BUNDLE_PROPERTIES "Java 無法與下載伺服器進行通訊。程式將立即結束。"
IDS_ERROR_MALFORMED_BUNDLE_PROPERTIES "Java 在與下載伺服器進行通訊時遇到了一個錯誤。程式將立即結束。"
IDS_ERROR_MALFORMED_URL "Java 無法從 URL「%s」下載。程式將立即結束。"
END
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
//
//
// HTTP status code
#define IDS_HTTP_STATUS_FORBIDDEN 403
#define IDS_HTTP_STATUS_REQUEST_TIMEOUT 408
#define IDS_HTTP_STATUS_SERVER_ERROR 500
#define IDS_HTTP_STATUS_SERVICE_UNAVAIL 503
#define IDS_HTTP_INSTRUCTION_REQUEST_TIMEOUT 2408
#define IDS_HTTP_INSTRUCTION_SERVICE_UNAVAIL 2503
#define IDS_HTTP_INSTRUCTION_FORBIDDEN 2403
#define IDS_HTTP_INSTRUCTION_SERVER_NOT_REACHABLE 2035
#define IDS_HTTP_INSTRUCTION_UNKNOWN_ERROR 2036
#define IDS_HTTP_STATUS_OTHER 2037
#define IDS_DOWNLOAD_STATUS_RETRY 3004
#define IDD_DOWNLOAD_DIALOG 105
#define IDI_JAVA 114
#define IDI_MASTHEAD 115
#define IDC_DOWNLOAD_PROGRESS 1006
#define IDC_DOWNLOAD_INFO 1007
#define IDC_DOWNLOAD_STATUS 1008
#define IDC_DOWNLOAD_ANIMATE 1009
#define IDS_ERROR_CAPTION 2004
#define IDS_HOURSMINUTESECOND 2007
#define IDS_HOURMINUTESECOND 2008
#define IDS_MINUTESECOND 2009
#define IDS_SECOND 2010
#define IDS_DISK_FULL_ERROR 2023
#define IDS_DISK_FULL_ERROR_CAPTION 2024
#define IDS_DISK_WRITE_ERROR 2025
#define IDS_DISK_WRITE_ERROR_CAPTION 2026
#define IDS_HTTP_STATUS_SERVER_NOT_REACHABLE 2028
#define IDS_FATAL_ERROR 2029
#define IDS_ERROR_DOWNLOADING_BUNDLE_PROPERTIES 2030
#define IDS_ERROR_MALFORMED_BUNDLE_PROPERTIES 2031
#define IDS_ERROR_MALFORMED_URL 2032
#define IDS_DOWNLOAD_CANCEL_CAPTION 2038
#define IDS_DOWNLOAD_CANCEL_INSTRUCTION 2039
#define IDS_DOWNLOAD_CANCEL_MESSAGE 2040
// codes for download and install dialog
#define IDC_MASTHEAD_TEXT 116
#define IDC_DOWNLOAD_MASTHEAD 121
#define IDC_TIME_REMAINING 122
#define IDC_DOWNLOAD_TEXT 123
// codes for download retry dialog
#define IDS_DOWNLOAD_RETRY 130
#define IDS_DOWNLOAD_RETRY_TEXT 131
#define IDS_DOWNLOAD_UNPACKING 3900
#define IDS_DOWNLOAD 4000
#define IDS_DOWNLOAD_TEXT 4001
// codes for completion cleanup
#define IDS_FILE_UPDATE_ERROR 4101
#define IDS_FILE_DELETE_ERROR 4103
#define IDS_JAVA_HOME_ERROR 4104
#define IDS_KERNEL_HOME_ERROR 4105
#define IDS_JBROKER_ERROR 4106
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 128
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1016
#define _APS_NEXT_SYMED_VALUE 103
#endif
#endif
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
// stdafx.cpp : source file that includes just the standard includes
// stdafx.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
#ifdef _ATL_STATIC_REGISTRY
#include <statreg.h>
#include <statreg.cpp>
#endif
#include <atlimpl.cpp>
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently,
// but are changed infrequently
#if !defined(AFX_STDAFX_H__FBC6C744_18F8_11D6_9DF1_0001023B10AA__INCLUDED_)
#define AFX_STDAFX_H__FBC6C744_18F8_11D6_9DF1_0001023B10AA__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define STRICT
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif
#define _ATL_APARTMENT_THREADED
#include <atlbase.h>
//You may derive a class from CComModule and use it if you want to override
//something, but do not change the name of _Module
extern CComModule _Module;
#include <atlcom.h>
#include <atlwin.h>
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__FBC6C744_18F8_11D6_9DF1_0001023B10AA__INCLUDED)
/*
* Copyright 2008 - 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
#include "afxres.h"
// Need 2 defines so macro argument to XSTR will get expanded before quoting.
#define XSTR(x) STR(x)
#define STR(x) #x
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION JDK_FVER
PRODUCTVERSION JDK_FVER
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
// FILEOS 0x4 is Win32, 0x40004 is Win32 NT only
FILEOS 0x4L
// FILETYPE should be 0x1 for .exe and 0x2 for .dll
FILETYPE JDK_FTYPE
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "000004b0"
BEGIN
VALUE "CompanyName", XSTR(JDK_COMPANY) "\0"
VALUE "FileDescription", XSTR(JDK_COMPONENT) "\0"
VALUE "FileVersion", XSTR(JDK_VER) "\0"
VALUE "Full Version", XSTR(JDK_BUILD_ID) "\0"
VALUE "InternalName", XSTR(JDK_INTERNAL_NAME) "\0"
VALUE "LegalCopyright", XSTR(JDK_COPYRIGHT) "\0"
VALUE "OriginalFilename", XSTR(JDK_FNAME) "\0"
VALUE "ProductName", XSTR(JDK_NAME) "\0"
VALUE "ProductVersion", XSTR(JDK_VER) "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0, 1200
END
END
...@@ -48,8 +48,8 @@ SECURITY_WARNING_2 ICON DISCARDABLE "security_warning.ico" ...@@ -48,8 +48,8 @@ SECURITY_WARNING_2 ICON DISCARDABLE "security_warning.ico"
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION J2SE_FVER FILEVERSION JDK_FVER
PRODUCTVERSION J2SE_FVER PRODUCTVERSION JDK_FVER
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
...@@ -59,22 +59,22 @@ VS_VERSION_INFO VERSIONINFO ...@@ -59,22 +59,22 @@ VS_VERSION_INFO VERSIONINFO
// FILEOS 0x4 is Win32, 0x40004 is Win32 NT only // FILEOS 0x4 is Win32, 0x40004 is Win32 NT only
FILEOS 0x4L FILEOS 0x4L
// FILETYPE should be 0x1 for .exe and 0x2 for .dll // FILETYPE should be 0x1 for .exe and 0x2 for .dll
FILETYPE J2SE_FTYPE FILETYPE JDK_FTYPE
FILESUBTYPE 0x0L FILESUBTYPE 0x0L
BEGIN BEGIN
BLOCK "StringFileInfo" BLOCK "StringFileInfo"
BEGIN BEGIN
BLOCK "040904b0" BLOCK "040904b0"
BEGIN BEGIN
VALUE "CompanyName", XSTR(J2SE_COMPANY) "\0" VALUE "CompanyName", XSTR(JDK_COMPANY) "\0"
VALUE "FileDescription", XSTR(J2SE_COMPONENT) "\0" VALUE "FileDescription", XSTR(JDK_COMPONENT) "\0"
VALUE "FileVersion", XSTR(J2SE_VER) "\0" VALUE "FileVersion", XSTR(JDK_VER) "\0"
VALUE "Full Version", XSTR(J2SE_BUILD_ID) "\0" VALUE "Full Version", XSTR(JDK_BUILD_ID) "\0"
VALUE "InternalName", XSTR(J2SE_INTERNAL_NAME) "\0" VALUE "InternalName", XSTR(JDK_INTERNAL_NAME) "\0"
VALUE "LegalCopyright", XSTR(J2SE_COPYRIGHT) "\0" VALUE "LegalCopyright", XSTR(JDK_COPYRIGHT) "\0"
VALUE "OriginalFilename", XSTR(J2SE_FNAME) "\0" VALUE "OriginalFilename", XSTR(JDK_FNAME) "\0"
VALUE "ProductName", XSTR(J2SE_NAME) "\0" VALUE "ProductName", XSTR(JDK_NAME) "\0"
VALUE "ProductVersion", XSTR(J2SE_VER) "\0" VALUE "ProductVersion", XSTR(JDK_VER) "\0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"
......
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="IMVERSION"
processorArchitecture="X86"
name="unpack200.exe"
type="win32"/>
<description>Java(TM) SE Runtime Environment unpack200 Process.</description>
<!-- Identify the application security requirements. -->
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="asInvoker"
uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
...@@ -37,8 +37,8 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL ...@@ -37,8 +37,8 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION J2SE_FVER FILEVERSION JDK_FVER
PRODUCTVERSION J2SE_FVER PRODUCTVERSION JDK_FVER
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
...@@ -48,22 +48,22 @@ VS_VERSION_INFO VERSIONINFO ...@@ -48,22 +48,22 @@ VS_VERSION_INFO VERSIONINFO
// FILEOS 0x4 is Win32, 0x40004 is Win32 NT only // FILEOS 0x4 is Win32, 0x40004 is Win32 NT only
FILEOS 0x4L FILEOS 0x4L
// FILETYPE should be 0x1 for .exe and 0x2 for .dll // FILETYPE should be 0x1 for .exe and 0x2 for .dll
FILETYPE J2SE_FTYPE FILETYPE JDK_FTYPE
FILESUBTYPE 0x0L FILESUBTYPE 0x0L
BEGIN BEGIN
BLOCK "StringFileInfo" BLOCK "StringFileInfo"
BEGIN BEGIN
BLOCK "000004b0" BLOCK "000004b0"
BEGIN BEGIN
VALUE "CompanyName", XSTR(J2SE_COMPANY) "\0" VALUE "CompanyName", XSTR(JDK_COMPANY) "\0"
VALUE "FileDescription", XSTR(J2SE_COMPONENT) "\0" VALUE "FileDescription", XSTR(JDK_COMPONENT) "\0"
VALUE "FileVersion", XSTR(J2SE_VER) "\0" VALUE "FileVersion", XSTR(JDK_VER) "\0"
VALUE "Full Version", XSTR(J2SE_BUILD_ID) "\0" VALUE "Full Version", XSTR(JDK_BUILD_ID) "\0"
VALUE "InternalName", XSTR(J2SE_INTERNAL_NAME) "\0" VALUE "InternalName", XSTR(JDK_INTERNAL_NAME) "\0"
VALUE "LegalCopyright", XSTR(J2SE_COPYRIGHT) "\0" VALUE "LegalCopyright", XSTR(JDK_COPYRIGHT) "\0"
VALUE "OriginalFilename", XSTR(J2SE_FNAME) "\0" VALUE "OriginalFilename", XSTR(JDK_FNAME) "\0"
VALUE "ProductName", XSTR(J2SE_NAME) "\0" VALUE "ProductName", XSTR(JDK_NAME) "\0"
VALUE "ProductVersion", XSTR(J2SE_VER) "\0" VALUE "ProductVersion", XSTR(JDK_VER) "\0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"
......
...@@ -416,5 +416,3 @@ class GlobalListener implements AWTEventListener { ...@@ -416,5 +416,3 @@ class GlobalListener implements AWTEventListener {
// } // }
} }
} }
...@@ -105,4 +105,3 @@ class TestFailedException extends RuntimeException { ...@@ -105,4 +105,3 @@ class TestFailedException extends RuntimeException {
super("Test failed: " + msg); super("Test failed: " + msg);
} }
} }
...@@ -66,4 +66,3 @@ public class TranslatedOutlineTest { ...@@ -66,4 +66,3 @@ public class TranslatedOutlineTest {
throw new RuntimeException("Outline was not detected"); throw new RuntimeException("Outline was not detected");
} }
} }
...@@ -85,5 +85,3 @@ public class FontThread extends Thread { ...@@ -85,5 +85,3 @@ public class FontThread extends Thread {
} }
} }
} }
...@@ -47,4 +47,3 @@ public class FailureDebugOption { ...@@ -47,4 +47,3 @@ public class FailureDebugOption {
} }
} }
} }
...@@ -109,5 +109,3 @@ public class bug6691503 { ...@@ -109,5 +109,3 @@ public class bug6691503 {
}); });
} }
} }
...@@ -106,4 +106,3 @@ public class TestRSACipherWrap extends PKCS11Test { ...@@ -106,4 +106,3 @@ public class TestRSACipherWrap extends PKCS11Test {
main(new TestRSACipherWrap()); main(new TestRSACipherWrap());
} }
} }
...@@ -113,4 +113,3 @@ public class AsyncSSLSocketClose implements Runnable ...@@ -113,4 +113,3 @@ public class AsyncSSLSocketClose implements Runnable
} }
} }
...@@ -305,4 +305,3 @@ public class CloseKeepAliveCached { ...@@ -305,4 +305,3 @@ public class CloseKeepAliveCached {
} }
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册