| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- /*
- * Licensed to Elasticsearch under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
- package org.elasticsearch.bootstrap;
- import com.sun.jna.IntegerType;
- import com.sun.jna.Native;
- import com.sun.jna.NativeLong;
- import com.sun.jna.Pointer;
- import com.sun.jna.Structure;
- import com.sun.jna.WString;
- import com.sun.jna.win32.StdCallLibrary;
- import org.apache.logging.log4j.LogManager;
- import org.apache.logging.log4j.Logger;
- import org.apache.lucene.util.Constants;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collections;
- import java.util.List;
- /**
- * Library for Windows/Kernel32
- */
- final class JNAKernel32Library {
- private static final Logger logger = LogManager.getLogger(JNAKernel32Library.class);
- // Callbacks must be kept around in order to be able to be called later,
- // when the Windows ConsoleCtrlHandler sends an event.
- private List<NativeHandlerCallback> callbacks = new ArrayList<>();
- // Native library instance must be kept around for the same reason.
- private static final class Holder {
- private static final JNAKernel32Library instance = new JNAKernel32Library();
- }
- private JNAKernel32Library() {
- if (Constants.WINDOWS) {
- try {
- Native.register("kernel32");
- logger.debug("windows/Kernel32 library loaded");
- } catch (NoClassDefFoundError e) {
- logger.warn("JNA not found. native methods and handlers will be disabled.");
- } catch (UnsatisfiedLinkError e) {
- logger.warn("unable to link Windows/Kernel32 library. native methods and handlers will be disabled.");
- }
- }
- }
- static JNAKernel32Library getInstance() {
- return Holder.instance;
- }
- /**
- * Adds a Console Ctrl Handler.
- *
- * @return true if the handler is correctly set
- * @throws java.lang.UnsatisfiedLinkError if the Kernel32 library is not loaded or if the native function is not found
- * @throws java.lang.NoClassDefFoundError if the library for native calls is missing
- */
- boolean addConsoleCtrlHandler(ConsoleCtrlHandler handler) {
- boolean result = false;
- if (handler != null) {
- NativeHandlerCallback callback = new NativeHandlerCallback(handler);
- result = SetConsoleCtrlHandler(callback, true);
- if (result) {
- callbacks.add(callback);
- }
- }
- return result;
- }
- List<Object> getCallbacks() {
- return Collections.<Object>unmodifiableList(callbacks);
- }
- /**
- * Native call to the Kernel32 API to set a new Console Ctrl Handler.
- *
- * @return true if the handler is correctly set
- * @throws java.lang.UnsatisfiedLinkError if the Kernel32 library is not loaded or if the native function is not found
- * @throws java.lang.NoClassDefFoundError if the library for native calls is missing
- */
- native boolean SetConsoleCtrlHandler(StdCallLibrary.StdCallCallback handler, boolean add);
- /**
- * Handles consoles event with WIN API
- * <p>
- * See http://msdn.microsoft.com/en-us/library/windows/desktop/ms683242%28v=vs.85%29.aspx
- */
- class NativeHandlerCallback implements StdCallLibrary.StdCallCallback {
- private final ConsoleCtrlHandler handler;
- NativeHandlerCallback(ConsoleCtrlHandler handler) {
- this.handler = handler;
- }
- public boolean callback(long dwCtrlType) {
- int event = (int) dwCtrlType;
- if (logger.isDebugEnabled()) {
- logger.debug("console control handler receives event [{}@{}]", event, dwCtrlType);
- }
- return handler.handle(event);
- }
- }
- /**
- * Memory protection constraints
- *
- * https://msdn.microsoft.com/en-us/library/windows/desktop/aa366786%28v=vs.85%29.aspx
- */
- public static final int PAGE_NOACCESS = 0x0001;
- public static final int PAGE_GUARD = 0x0100;
- public static final int MEM_COMMIT = 0x1000;
- /**
- * Contains information about a range of pages in the virtual address space of a process.
- * The VirtualQuery and VirtualQueryEx functions use this structure.
- *
- * https://msdn.microsoft.com/en-us/library/windows/desktop/aa366775%28v=vs.85%29.aspx
- */
- public static class MemoryBasicInformation extends Structure {
- public Pointer BaseAddress;
- public Pointer AllocationBase;
- public NativeLong AllocationProtect;
- public SizeT RegionSize;
- public NativeLong State;
- public NativeLong Protect;
- public NativeLong Type;
- @Override
- protected List<String> getFieldOrder() {
- return Arrays.asList("BaseAddress", "AllocationBase", "AllocationProtect", "RegionSize", "State", "Protect", "Type");
- }
- }
- public static class SizeT extends IntegerType {
- // JNA requires this no-arg constructor to be public,
- // otherwise it fails to register kernel32 library
- public SizeT() {
- this(0);
- }
- SizeT(long value) {
- super(Native.SIZE_T_SIZE, value);
- }
- }
- /**
- * Locks the specified region of the process's virtual address space into physical
- * memory, ensuring that subsequent access to the region will not incur a page fault.
- *
- * https://msdn.microsoft.com/en-us/library/windows/desktop/aa366895%28v=vs.85%29.aspx
- *
- * @param address A pointer to the base address of the region of pages to be locked.
- * @param size The size of the region to be locked, in bytes.
- * @return true if the function succeeds
- */
- native boolean VirtualLock(Pointer address, SizeT size);
- /**
- * Retrieves information about a range of pages within the virtual address space of a specified process.
- *
- * https://msdn.microsoft.com/en-us/library/windows/desktop/aa366907%28v=vs.85%29.aspx
- *
- * @param handle A handle to the process whose memory information is queried.
- * @param address A pointer to the base address of the region of pages to be queried.
- * @param memoryInfo A pointer to a structure in which information about the specified page range is returned.
- * @param length The size of the buffer pointed to by the memoryInfo parameter, in bytes.
- * @return the actual number of bytes returned in the information buffer.
- */
- native int VirtualQueryEx(Pointer handle, Pointer address, MemoryBasicInformation memoryInfo, int length);
- /**
- * Sets the minimum and maximum working set sizes for the specified process.
- *
- * https://msdn.microsoft.com/en-us/library/windows/desktop/ms686234%28v=vs.85%29.aspx
- *
- * @param handle A handle to the process whose working set sizes is to be set.
- * @param minSize The minimum working set size for the process, in bytes.
- * @param maxSize The maximum working set size for the process, in bytes.
- * @return true if the function succeeds.
- */
- native boolean SetProcessWorkingSetSize(Pointer handle, SizeT minSize, SizeT maxSize);
- /**
- * Retrieves a pseudo handle for the current process.
- *
- * https://msdn.microsoft.com/en-us/library/windows/desktop/ms683179%28v=vs.85%29.aspx
- *
- * @return a pseudo handle to the current process.
- */
- native Pointer GetCurrentProcess();
- /**
- * Closes an open object handle.
- *
- * https://msdn.microsoft.com/en-us/library/windows/desktop/ms724211%28v=vs.85%29.aspx
- *
- * @param handle A valid handle to an open object.
- * @return true if the function succeeds.
- */
- native boolean CloseHandle(Pointer handle);
- /**
- * Retrieves the short path form of the specified path. See
- * <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa364989.aspx">{@code GetShortPathName}</a>.
- *
- * @param lpszLongPath the path string
- * @param lpszShortPath a buffer to receive the short name
- * @param cchBuffer the size of the buffer
- * @return the length of the string copied into {@code lpszShortPath}, otherwise zero for failure
- */
- native int GetShortPathNameW(WString lpszLongPath, char[] lpszShortPath, int cchBuffer);
- /**
- * Creates or opens a new job object
- *
- * https://msdn.microsoft.com/en-us/library/windows/desktop/ms682409%28v=vs.85%29.aspx
- *
- * @param jobAttributes security attributes
- * @param name job name
- * @return job handle if the function succeeds
- */
- native Pointer CreateJobObjectW(Pointer jobAttributes, String name);
- /**
- * Associates a process with an existing job
- *
- * https://msdn.microsoft.com/en-us/library/windows/desktop/ms681949%28v=vs.85%29.aspx
- *
- * @param job job handle
- * @param process process handle
- * @return true if the function succeeds
- */
- native boolean AssignProcessToJobObject(Pointer job, Pointer process);
- /**
- * Basic limit information for a job object
- *
- * https://msdn.microsoft.com/en-us/library/windows/desktop/ms684147%28v=vs.85%29.aspx
- */
- public static class JOBOBJECT_BASIC_LIMIT_INFORMATION extends Structure implements Structure.ByReference {
- public long PerProcessUserTimeLimit;
- public long PerJobUserTimeLimit;
- public int LimitFlags;
- public SizeT MinimumWorkingSetSize;
- public SizeT MaximumWorkingSetSize;
- public int ActiveProcessLimit;
- public Pointer Affinity;
- public int PriorityClass;
- public int SchedulingClass;
- @Override
- protected List<String> getFieldOrder() {
- return Arrays.asList("PerProcessUserTimeLimit", "PerJobUserTimeLimit", "LimitFlags", "MinimumWorkingSetSize",
- "MaximumWorkingSetSize", "ActiveProcessLimit", "Affinity", "PriorityClass", "SchedulingClass");
- }
- }
- /**
- * Constant for JOBOBJECT_BASIC_LIMIT_INFORMATION in Query/Set InformationJobObject
- */
- static final int JOBOBJECT_BASIC_LIMIT_INFORMATION_CLASS = 2;
- /**
- * Constant for LimitFlags, indicating a process limit has been set
- */
- static final int JOB_OBJECT_LIMIT_ACTIVE_PROCESS = 8;
- /**
- * Get job limit and state information
- *
- * https://msdn.microsoft.com/en-us/library/windows/desktop/ms684925%28v=vs.85%29.aspx
- *
- * @param job job handle
- * @param infoClass information class constant
- * @param info pointer to information structure
- * @param infoLength size of information structure
- * @param returnLength length of data written back to structure (or null if not wanted)
- * @return true if the function succeeds
- */
- native boolean QueryInformationJobObject(Pointer job, int infoClass, Pointer info, int infoLength, Pointer returnLength);
- /**
- * Set job limit and state information
- *
- * https://msdn.microsoft.com/en-us/library/windows/desktop/ms686216%28v=vs.85%29.aspx
- *
- * @param job job handle
- * @param infoClass information class constant
- * @param info pointer to information structure
- * @param infoLength size of information structure
- * @return true if the function succeeds
- */
- native boolean SetInformationJobObject(Pointer job, int infoClass, Pointer info, int infoLength);
- }
|