diff --git a/CHANGES.md b/CHANGES.md index 7c94a078c1..8f6cc65afb 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,9 +12,14 @@ Features * [#1168](https://github.com/java-native-access/jna/pull/1168): Add `c.s.j.p.win32.Kernel32#SetProcessAffinityMask` - [@dbwiddis](https://github.com/dbwiddis). * [#1169](https://github.com/java-native-access/jna/issues/1169): Wait for process in getLinuxLdPaths - [@rdesgroppes](https://github.com/rdesgroppes). * [#1178](https://github.com/java-native-access/jna/pull/1178): Add `c.s.j.p.win32.IPHlpAPI#GetTcpStatistics`, `c.s.j.p.win32.IPHlpAPI#GetUdpStatistics`, `c.s.j.p.win32.IPHlpAPI#GetTcpStatisticsEx` and `c.s.j.p.win32.IPHlpAPI#GetUdpStatisticsEx` - [@dbwiddis](https://github.com/dbwiddis). -* [#1191](https://github.com/java-native-access/jna/pull/1191): Add `c.s.j.p.win32.Advapi32Util#getTokenPrimaryGroup` - [@dbwiddis](https://github.com/dbwiddis). * [#1182](https://github.com/java-native-access/jna/pull/1182): Add `toString` to classes extending `c.s.j.ptr.ByReference` - [@dbwiddis](https://github.com/dbwiddis). +* [#1191](https://github.com/java-native-access/jna/pull/1191): Add `c.s.j.p.win32.Advapi32Util#getTokenPrimaryGroup` - [@dbwiddis](https://github.com/dbwiddis). * [#1194](https://github.com/java-native-access/jna/pull/1194): Add `GetConsoleScreenBufferInfo`, `ReadConsoleInput` and `WriteConsole` with associated structures to `c.s.j.p.win32.Wincon` - [@rednoah](https://github.com/rednoah). +* [#1198](https://github.com/java-native-access/jna/pull/1198): Add `NetSessionEnum` to `c.s.j.p.win32.Netapi32` and `WTSEnumerateSessions`, `WTSQuerySessionInformation`, and `WTSFreeMemory` to `c.s.j.p.win32.Wtsapi32` - [@dbwiddis](https://github.com/dbwiddis). +* [#1200](https://github.com/java-native-access/jna/pull/1200): Add mappings for `libudev` to `c.s.j.p.linux.Udev` - [@dbwiddis](https://github.com/dbwiddis). +* [#1202](https://github.com/java-native-access/jna/pull/1202): Add mappings supporting shared memory including `c.s.j.p.unix.LibCAPI` types `size_t` and `ssize_t`, `c.s.j.p.linux.LibC` methods `munmap()`, `msync()`, and `close()`, `c.s.j.p.unix.LibCUtil` mapping `mmap()` and `ftruncate()`, and `c.s.j.p.linux.LibRT` methods `shm_open()` and `shm_unlink()` - [@dbwiddis](https://github.com/dbwiddis). +* [#1209](https://github.com/java-native-access/jna/pull/1209): Add mappings for `Thread32First` and `Thread32Next` to `c.s.j.p.win32.Kernel32` - [@dbwiddis](https://github.com/dbwiddis). +* [#1214](https://github.com/java-native-access/jna/pull/1214): Add mapping for EnumProcesses to `c.s.j.p.win32.Psapi` - [@T-Svensson](https://github.com/T-Svensson/). Bug Fixes --------- diff --git a/contrib/platform/src/com/sun/jna/platform/linux/ErrNo.java b/contrib/platform/src/com/sun/jna/platform/linux/ErrNo.java new file mode 100644 index 0000000000..95b59fc233 --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/linux/ErrNo.java @@ -0,0 +1,162 @@ +/* Copyright (c) 2020 Daniel Widdis, All Rights Reserved + * + * The contents of this file is dual-licensed under 2 + * alternative Open Source/Free licenses: LGPL 2.1 or later and + * Apache License 2.0. (starting with JNA version 4.0.0). + * + * You can freely decide which license you want to apply to + * the project. + * + * You may obtain a copy of the LGPL License at: + * + * http://www.gnu.org/licenses/licenses.html + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "LGPL2.1". + * + * You may obtain a copy of the Apache License at: + * + * http://www.apache.org/licenses/ + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "AL2.0". + */ +package com.sun.jna.platform.linux; + +import com.sun.jna.Native; + +/** + * System error codes set in {@code errno} and retrieved by + * {@link Native#getLastError()} + */ +public interface ErrNo { + int EPERM = 1; // Operation not permitted + int ENOENT = 2; // No such file or directory + int ESRCH = 3; // No such process + int EINTR = 4; // Interrupted system call + int EIO = 5; // I/O error + int ENXIO = 6; // No such device or address + int E2BIG = 7; // Argument list too long + int ENOEXEC = 8; // Exec format error + int EBADF = 9; // Bad file number + int ECHILD = 10; // No child processes + int EAGAIN = 11; // Try again + int ENOMEM = 12; // Out of memory + int EACCES = 13; // Permission denied + int EFAULT = 14; // Bad address + int ENOTBLK = 15; // Block device required + int EBUSY = 16; // Device or resource busy + int EEXIST = 17; // File exists + int EXDEV = 18; // Cross-device link + int ENODEV = 19; // No such device + int ENOTDIR = 20; // Not a directory + int EISDIR = 21; // Is a directory + int EINVAL = 22; // Invalid argument + int ENFILE = 23; // File table overflow + int EMFILE = 24; // Too many open files + int ENOTTY = 25; // Not a typewriter + int ETXTBSY = 26; // Text file busy + int EFBIG = 27; // File too large + int ENOSPC = 28; // No space left on device + int ESPIPE = 29; // Illegal seek + int EROFS = 30; // Read-only file system + int EMLINK = 31; // Too many links + int EPIPE = 32; // Broken pipe + int EDOM = 33; // Math argument out of domain of func + int ERANGE = 34; // Math result not representable + int EDEADLK = 35; // Resource deadlock would occur + int ENAMETOOLONG = 36; // File name too long + int ENOLCK = 37; // No record locks available + int ENOSYS = 38; // Function not implemented + int ENOTEMPTY = 39; // Directory not empty + int ELOOP = 40; // Too many symbolic links encountered + int ENOMSG = 42; // No message of desired type + int EIDRM = 43; // Identifier removed + int ECHRNG = 44; // Channel number out of range + int EL2NSYNC = 45; // Level 2 not synchronized + int EL3HLT = 46; // Level 3 halted + int EL3RST = 47; // Level 3 reset + int ELNRNG = 48; // Link number out of range + int EUNATCH = 49; // Protocol driver not attached + int ENOCSI = 50; // No CSI structure available + int EL2HLT = 51; // Level 2 halted + int EBADE = 52; // Invalid exchange + int EBADR = 53; // Invalid request descriptor + int EXFULL = 54; // Exchange full + int ENOANO = 55; // No anode + int EBADRQC = 56; // Invalid request code + int EBADSLT = 57; // Invalid slot + int EBFONT = 59; // Bad font file format + int ENOSTR = 60; // Device not a stream + int ENODATA = 61; // No data available + int ETIME = 62; // Timer expired + int ENOSR = 63; // Out of streams resources + int ENONET = 64; // Machine is not on the network + int ENOPKG = 65; // Package not installed + int EREMOTE = 66; // Object is remote + int ENOLINK = 67; // Link has been severed + int EADV = 68; // Advertise error + int ESRMNT = 69; // Srmount error + int ECOMM = 70; // Communication error on send + int EPROTO = 71; // Protocol error + int EMULTIHOP = 72; // Multihop attempted + int EDOTDOT = 73; // RFS specific error + int EBADMSG = 74; // Not a data message + int EOVERFLOW = 75; // Value too large for defined data type + int ENOTUNIQ = 76; // Name not unique on network + int EBADFD = 77; // File descriptor in bad state + int EREMCHG = 78; // Remote address changed + int ELIBACC = 79; // Can not access a needed shared library + int ELIBBAD = 80; // Accessing a corrupted shared library + int ELIBSCN = 81; // .lib section in a.out corrupted + int ELIBMAX = 82; // Attempting to link in too many shared libraries + int ELIBEXEC = 83; // Cannot exec a shared library directly + int EILSEQ = 84; // Illegal byte sequence + int ERESTART = 85; // Interrupted system call should be restarted + int ESTRPIPE = 86; // Streams pipe error + int EUSERS = 87; // Too many users + int ENOTSOCK = 88; // Socket operation on non-socket + int EDESTADDRREQ = 89; // Destination address required + int EMSGSIZE = 90; // Message too long + int EPROTOTYPE = 91; // Protocol wrong type for socket + int ENOPROTOOPT = 92; // Protocol not available + int EPROTONOSUPPORT = 93; // Protocol not supported + int ESOCKTNOSUPPORT = 94; // Socket type not supported + int EOPNOTSUPP = 95; // Operation not supported on transport endpoint + int EPFNOSUPPORT = 96; // Protocol family not supported + int EAFNOSUPPORT = 97; // Address family not supported by protocol + int EADDRINUSE = 98; // Address already in use + int EADDRNOTAVAIL = 99; // Cannot assign requested address + int ENETDOWN = 100; // Network is down + int ENETUNREACH = 101; // Network is unreachable + int ENETRESET = 102; // Network dropped connection because of reset + int ECONNABORTED = 103; // Software caused connection abort + int ECONNRESET = 104; // Connection reset by peer + int ENOBUFS = 105; // No buffer space available + int EISCONN = 106; // Transport endpoint is already connected + int ENOTCONN = 107; // Transport endpoint is not connected + int ESHUTDOWN = 108; // Cannot send after transport endpoint shutdown + int ETOOMANYREFS = 109; // Too many references: cannot splice + int ETIMEDOUT = 110; // Connection timed out + int ECONNREFUSED = 111; // Connection refused + int EHOSTDOWN = 112; // Host is down + int EHOSTUNREACH = 113; // No route to host + int EALREADY = 114; // Operation already in progress + int EINPROGRESS = 115; // Operation now in progress + int ESTALE = 116; // Stale NFS file handle + int EUCLEAN = 117; // Structure needs cleaning + int ENOTNAM = 118; // Not a XENIX named type file + int ENAVAIL = 119; // No XENIX semaphores available + int EISNAM = 120; // Is a named type file + int EREMOTEIO = 121; // Remote I/O error + int EDQUOT = 122; // Quota exceeded + int ENOMEDIUM = 123; // No medium found + int EMEDIUMTYPE = 124; // Wrong medium type + int ECANCELED = 125; // Operation Canceled + int ENOKEY = 126; // Required key not available + int EKEYEXPIRED = 127; // Key has expired + int EKEYREVOKED = 128; // Key has been revoked + int EKEYREJECTED = 129; // Key was rejected by service + int EOWNERDEAD = 130; // Owner died + int ENOTRECOVERABLE = 131; // State not recoverable +} \ No newline at end of file diff --git a/contrib/platform/src/com/sun/jna/platform/linux/Fcntl.java b/contrib/platform/src/com/sun/jna/platform/linux/Fcntl.java new file mode 100644 index 0000000000..c5afe0dd5a --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/linux/Fcntl.java @@ -0,0 +1,64 @@ +/* Copyright (c) 2020 Daniel Widdis, All Rights Reserved + * + * The contents of this file is dual-licensed under 2 + * alternative Open Source/Free licenses: LGPL 2.1 or later and + * Apache License 2.0. (starting with JNA version 4.0.0). + * + * You can freely decide which license you want to apply to + * the project. + * + * You may obtain a copy of the LGPL License at: + * + * http://www.gnu.org/licenses/licenses.html + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "LGPL2.1". + * + * You may obtain a copy of the Apache License at: + * + * http://www.apache.org/licenses/ + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "AL2.0". + */ +package com.sun.jna.platform.linux; + +/** + * POSIX Standard: 6.5 File Control Operations from {@code fcntl.h} + */ +public interface Fcntl { + /* + * File access modes for `open' and `fcntl' + */ + int O_RDONLY = 00; // Open read-only. + int O_WRONLY = 01; // Open write-only. + int O_RDWR = 02; // Open read/write. + + /* + * Bits OR'd into the second argument to open. Note these are defined + * differently on linux than unix fcntl header + */ + int O_CREAT = 0100; // Create file if it doesn't exist. + int O_EXCL = 0200; // Fail if file already exists. + int O_TRUNC = 01000; // Truncate file to zero length. + + /* Protection bits. */ + int S_IRUSR = 00400; // Read by owner. + int S_IWUSR = 00200; // Write by owner. + int S_IXUSR = 00100; // Execute by owner. + int S_IRWXU = S_IRUSR | S_IWUSR | S_IXUSR; + + int S_IRGRP = 00040; // Read by group. + int S_IWGRP = 00020; // Write by group. + int S_IXGRP = 00010; // Execute by group. + int S_IRWXG = S_IRGRP | S_IWGRP | S_IXGRP; + + int S_IROTH = 00004; // Read by others. + int S_IWOTH = 00002; // Write by others. + int S_IXOTH = 00001; // Execute by others. + int S_IRWXO = S_IROTH | S_IWOTH | S_IXOTH; + + int S_ISUID = 04000; // set-user-ID bit + int S_ISGID = 02000; // set-group-ID bit (see inode(7)). + int S_ISVTX = 01000; // sticky bit (see inode(7)). +} diff --git a/contrib/platform/src/com/sun/jna/platform/linux/LibRT.java b/contrib/platform/src/com/sun/jna/platform/linux/LibRT.java new file mode 100644 index 0000000000..0a87da670f --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/linux/LibRT.java @@ -0,0 +1,73 @@ +/* Copyright (c) 2020 Daniel Widdis, All Rights Reserved + * + * The contents of this file is dual-licensed under 2 + * alternative Open Source/Free licenses: LGPL 2.1 or later and + * Apache License 2.0. (starting with JNA version 4.0.0). + * + * You can freely decide which license you want to apply to + * the project. + * + * You may obtain a copy of the LGPL License at: + * + * http://www.gnu.org/licenses/licenses.html + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "LGPL2.1". + * + * You may obtain a copy of the Apache License at: + * + * http://www.apache.org/licenses/ + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "AL2.0". + */ +package com.sun.jna.platform.linux; + +import com.sun.jna.Library; +import com.sun.jna.Native; + +/** + * POSIX.1b Realtime Extensions library (librt). Functions in this library + * provide most of the interfaces specified by the POSIX.1b Realtime Extension. + */ +public interface LibRT extends Library { + + LibRT INSTANCE = Native.load("rt", LibRT.class); + + /** + * Creates and opens a new, or opens an existing, POSIX shared memory object. A + * POSIX shared memory object is in effect a handle which can be used by + * unrelated processes to {@code mmap()} the same region of shared memory. + * + * @param name + * The shared memory object to be created or opened. For portable + * use, a shared memory object should be identified by a name of the + * form {@code /somename} that is, a null-terminated string of up to + * {@code NAME_MAX} (i.e., 255) characters consisting of an initial + * slash, followed by one or more characters, none of which are + * slashes. + * @param oflag + * A bit mask created by ORing together exactly one of + * {@code O_RDONLY} or {@code O_RDWR} and any of the other flags + * {@code O_CREAT}, {@code O_EXCL}, or {@code O_TRUNC}. + * @param mode + * When {@code oflag} includes {@code O_CREAT}, the object's + * permission bits are set according to the low-order 9 bits of mode, + * except that those bits set in the process file mode creation mask + * (see {@code umask(2)}) are cleared for the new object. + * @return On success, returns a file descriptor (a nonnegative integer). On + * failure, returns -1. On failure, {@code errno} is set to indicate the + * cause of the error. + */ + int shm_open(String name, int oflag, int mode); + + /** + * Removes an object previously created by {@link #shm_open}. + * + * @param name + * The shared memory object to be unlinked. + * @return returns 0 on success, or -1 on error. On failure, {@code errno} is + * set to indicate the cause of the error. + */ + int shm_unlink(String name); +} diff --git a/contrib/platform/src/com/sun/jna/platform/linux/Mman.java b/contrib/platform/src/com/sun/jna/platform/linux/Mman.java new file mode 100644 index 0000000000..f035e18503 --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/linux/Mman.java @@ -0,0 +1,77 @@ +/* Copyright (c) 2020 Daniel Widdis, All Rights Reserved + * + * The contents of this file is dual-licensed under 2 + * alternative Open Source/Free licenses: LGPL 2.1 or later and + * Apache License 2.0. (starting with JNA version 4.0.0). + * + * You can freely decide which license you want to apply to + * the project. + * + * You may obtain a copy of the LGPL License at: + * + * http://www.gnu.org/licenses/licenses.html + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "LGPL2.1". + * + * You may obtain a copy of the Apache License at: + * + * http://www.apache.org/licenses/ + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "AL2.0". + */ +package com.sun.jna.platform.linux; + +import com.sun.jna.Pointer; + +/** + * Definitions for POSIX memory map interface from {@code mman.h} + */ +public interface Mman { + /* + * Protections are chosen from these bits, OR'd together. The implementation + * does not necessarily support PROT_EXEC or PROT_WRITE without PROT_READ. The + * only guarantees are that no writing will be allowed without PROT_WRITE and no + * access will be allowed for PROT_NONE. + */ + int PROT_READ = 0x1; // Page can be read. + int PROT_WRITE = 0x2; // Page can be written. + int PROT_EXEC = 0x4; // Page can be executed. + int PROT_NONE = 0x0; // Page can not be accessed. + int PROT_GROWSDOWN = 0x01000000; // Extend change to start of growsdown vma (mprotect only). + int PROT_GROWSUP = 0x02000000; // Extend change to start of growsup vma (mprotect only). + + /* Sharing types (must choose one and only one of these). */ + int MAP_SHARED = 0x01; // Share changes. + int MAP_PRIVATE = 0x02; // Changes are private. + int MAP_SHARED_VALIDATE = 0x03; // share + validate extension flags + int MAP_TYPE = 0x0f; // Mask for type of mapping + + /* Other flags. */ + int MAP_FILE = 0; // Compatibility flag. Ignored. + int MAP_FIXED = 0x10; // Interpret addr exactly. + int MAP_ANONYMOUS = 0x20; // Don't use a file. + int MAP_ANON = MAP_ANONYMOUS; + int MAP_32BIT = 0x40; // Only give out 32-bit addresses. + + /* These are Linux-specific. */ + int MAP_GROWSDOWN = 0x00100; // Stack-like segment. + int MAP_DENYWRITE = 0x00800; // ETXTBSY + int MAP_EXECUTABLE = 0x01000; // Mark it as an executable. + int MAP_LOCKED = 0x02000; // Lock the mapping. + int MAP_NORESERVE = 0x04000; // Don't check for reservations. + int MAP_POPULATE = 0x08000; // Populate (prefault) pagetables. + int MAP_NONBLOCK = 0x10000; // Do not block on IO. + int MAP_STACK = 0x20000; // Allocation is for a stack. + int MAP_HUGETLB = 0x40000; // create a huge page mapping + int MAP_SYNC = 0x80000; // perform synchronous page faults for the mapping + int MAP_FIXED_NOREPLACE = 0x100000; // MAP_FIXED which doesn't unmap underlying mapping + + Pointer MAP_FAILED = new Pointer(-1); // ((void *)-1) + + /* Flags for msync. */ + int MS_ASYNC = 1; + int MS_SYNC = 2; + int MS_INVALIDATE = 4; +} diff --git a/contrib/platform/src/com/sun/jna/platform/linux/Udev.java b/contrib/platform/src/com/sun/jna/platform/linux/Udev.java new file mode 100644 index 0000000000..23db457cfa --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/linux/Udev.java @@ -0,0 +1,550 @@ +/* Copyright (c) 2020 Daniel Widdis, All Rights Reserved + * + * The contents of this file is dual-licensed under 2 + * alternative Open Source/Free licenses: LGPL 2.1 or later and + * Apache License 2.0. (starting with JNA version 4.0.0). + * + * You can freely decide which license you want to apply to + * the project. + * + * You may obtain a copy of the LGPL License at: + * + * http://www.gnu.org/licenses/licenses.html + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "LGPL2.1". + * + * You may obtain a copy of the Apache License at: + * + * http://www.apache.org/licenses/ + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "AL2.0". + */ +package com.sun.jna.platform.linux; + +import com.sun.jna.Library; +import com.sun.jna.Native; +import com.sun.jna.PointerType; + +/** + * libudev.h provides APIs to introspect and enumerate devices on the local + * system. Udev objects are opaque and must not be accessed by the caller via + * different means than functions provided by libudev. + */ +public interface Udev extends Library { + + Udev INSTANCE = Native.load("udev", Udev.class); + + /** + * All functions require a libudev context to operate. This context can be + * created via {@link #udev_new}. It is used to track library state and link + * objects together. No global state is used by libudev, everything is always + * linked to a udev context. Furthermore, multiple different udev contexts can + * be used in parallel by multiple threads. However, a single context must not + * be accessed by multiple threads in parallel. The caller is responsible for + * providing suitable locking if they intend to use it from multiple threads. + */ + class UdevContext extends PointerType { + /** + * Acquire a further reference to this object. + * + * @return this object, unmodified. + */ + UdevContext ref() { + return INSTANCE.udev_ref(this); + } + + /** + * Drop a reference to this object. Once the reference count hits 0, the context + * object is destroyed and freed. + */ + public void unref() { + INSTANCE.udev_unref(this); + } + + /** + * Create a udev enumerate object. Initially, the reference count of the + * enumerate object is 1. + * + * @return On success, returns the allocated enumerator. On failure, NULL is + * returned. + */ + public UdevEnumerate enumerateNew() { + return INSTANCE.udev_enumerate_new(this); + } + + /** + * Creates a udev device object based on information found in {@code /sys}, + * annotated with properties from the udev-internal device database. Initially, + * the reference count of the device is 1. + * + * @param syspath + * The path of the device in {@code /sys}. + * @return the allocated udev device. On failure, NULL is returned, and + * {@code errno} is set appropriately. + */ + public UdevDevice deviceNewFromSyspath(String syspath) { + return INSTANCE.udev_device_new_from_syspath(this, syspath); + } + } + + /** + * To enumerate local devices on the system, an enumeration object can be + * created via {@link UdevContext#enumerateNew()}. + */ + class UdevEnumerate extends PointerType { + /** + * Acquire a further reference to this object. + * + * @return this object, unmodified. + */ + public UdevEnumerate ref() { + return INSTANCE.udev_enumerate_ref(this); + } + + /** + * Drop a reference to this object. Once the reference count hits 0, the context + * object is destroyed and freed. + */ + public void unref() { + INSTANCE.udev_enumerate_unref(this); + } + + /** + * Modify filters of this object to match a subsystem. + * + * @param subsystem + * The subsystem to match + * @return an integer greater than, or equal to, 0 on success. + */ + public int addMatchSubsystem(String subsystem) { + return INSTANCE.udev_enumerate_add_match_subsystem(this, subsystem); + } + + /** + * Query this object. Scans {@code /sys} for all devices which match the given + * filters. No filters will return all currently available devices. + * + * @return an integer greater than, or equal to, 0 on success. + */ + public int scanDevices() { + return INSTANCE.udev_enumerate_scan_devices(this); + } + + /** + * Get the first list entry from this object. + * + * @return On success, returns the first entry in the list of found devices. If + * the list is empty, or on failure, NULL is returned. + */ + public UdevListEntry getListEntry() { + return INSTANCE.udev_enumerate_get_list_entry(this); + } + } + + /** + * Whenever libudev returns a list of objects, the {@code udev_list_entry} API + * should be used to iterate, access and modify those lists. + */ + class UdevListEntry extends PointerType { + /** + * Gets the next entry in the enumeration. + * + * @return On success, returns the next list entry. If no such entry can be + * found, or on failure, NULL is returned. + */ + public UdevListEntry getNext() { + return INSTANCE.udev_list_entry_get_next(this); + } + + /** + * Get the name of this entry, which is the path of the device in {@code /sys}. + * + * @return A string representing the syspath. On failure, NULL is returned. + */ + public String getName() { + return INSTANCE.udev_list_entry_get_name(this); + } + } + + /** + * To introspect a local device on a system, a udev device object can be created + * via {@link UdevContext#deviceNewFromSyspath(String)} and friends. The device + * object allows one to query current state, read and write attributes and + * lookup properties of the device in question. + */ + class UdevDevice extends PointerType { + /** + * Acquire a further reference to this object. + * + * @return this object, unmodified. + */ + public UdevDevice ref() { + return INSTANCE.udev_device_ref(this); + } + + /** + * Drop a reference to this object. Once the reference count hits 0, the context + * object is destroyed and freed. + */ + public void unref() { + INSTANCE.udev_device_unref(this); + } + + /** + * Gets the parent of this device + * + * @return the parent device. No additional reference to this device is + * acquired, but the child device owns a reference to the parent device. + * On failure, NULL is returned. + */ + public UdevDevice getParent() { + return INSTANCE.udev_device_get_parent(this); + } + + /** + * Gets the parent of this device matching a subsystem and devtype + * + * @param subsystem + * The subsystem to match + * @param devtype + * The device type to match + * @return the parent device. No additional reference to this device is + * acquired, but the child device owns a reference to the parent device. + * On failure, NULL is returned. + */ + public UdevDevice getParentWithSubsystemDevtype(String subsystem, String devtype) { + return INSTANCE.udev_device_get_parent_with_subsystem_devtype(this, subsystem, devtype); + } + + /** + * Gets the syspath of this device + * + * @return a string that describes the syspath. On failure, may return NULL. + */ + public String getSyspath() { + return INSTANCE.udev_device_get_syspath(this); + } + + /** + * Gets the sysname of this device + * + * @return a string that describes the sysname. On failure, may return NULL. + */ + public String getSysname() { + return INSTANCE.udev_device_get_syspath(this); + } + + /** + * Gets the devnode of this device + * + * @return a string that describes the devnode. On failure, may return NULL. + */ + public String getDevnode() { + return INSTANCE.udev_device_get_devnode(this); + } + + /** + * Gets the devtype of this device + * + * @return a string that describes the devtype. On failure, may return NULL. + */ + public String getDevtype() { + return INSTANCE.udev_device_get_devtype(this); + } + + /** + * Gets the subsystem of this device + * + * @return a string that describes the subsystem. On failure, may return NULL. + */ + public String getSubsystem() { + return INSTANCE.udev_device_get_subsystem(this); + } + + /** + * Retrieves a device attribute from this device + * + * @param sysattr + * The attribute to retrieve. + * @return a string of the requested value. On error, NULL is returned. + * Attributes that may contain NUL bytes should not be retrieved with + * udev_device_get_sysattr_value(); instead, read them directly from the + * files within the device's syspath. + */ + public String getSysattrValue(String sysattr) { + return INSTANCE.udev_device_get_sysattr_value(this, sysattr); + } + + /** + * Retrieves a device property from this device + * + * @param key + * The property to retrieve. + * @return a string of the requested value. On error, NULL is returned. + */ + public String getPropertyValue(String key) { + return INSTANCE.udev_device_get_property_value(this, key); + } + } + + /** + * Allocates a new udev context object and returns a pointer to it. This object + * is opaque and must not be accessed by the caller via different means than + * functions provided by libudev. Initially, the reference count of the context + * is 1. + * + * @return On success, returns a pointer to the allocated udev context. On + * failure, NULL is returned. + */ + UdevContext udev_new(); + + /** + * Acquire further references to a udev context object. + * + * @param udev + * A udev context object. + * @return the argument that was passed, unmodified. + */ + UdevContext udev_ref(UdevContext udev); + + /** + * Drop a reference to a udev context object. Once the reference count hits 0, + * the context object is destroyed and freed. + * + * @param udev + * A udev context object. + * @return always returns NULL. + */ + UdevContext udev_unref(UdevContext udev); + + /** + * Allocates a new udev device object and returns a pointer to it. This object + * is opaque and must not be accessed by the caller via different means than + * functions provided by libudev. Initially, the reference count of the device + * is 1. + *
+ * Creates the device object based on information found in {@code /sys}, + * annotated with properties from the udev-internal device database. A syspath + * is any subdirectory of {@code /sys}, with the restriction that a subdirectory + * of {@code /sys/devices} (or a symlink to one) represents a real device and as + * such must contain a uevent file. + * + * @param udev + * A udev context object. + * @param syspath + * The path of the device in {@code /sys}. + * @return a pointer to the allocated udev device. On failure, NULL is returned, + * and {@code errno} is set appropriately. + */ + UdevDevice udev_device_new_from_syspath(UdevContext udev, String syspath); + + /** + * Create a udev enumerate object. Initially, the reference count of the + * enumerate object is 1. + * + * @param udev + * A udev context object. + * @return On success, returns a pointer to the allocated udev monitor. On + * failure, NULL is returned. + */ + UdevEnumerate udev_enumerate_new(UdevContext udev); + + /** + * Acquire further references to a udev enumerate object. + * + * @param udev_enumerate + * A udev enumerate object. + * @return the argument that was passed, unmodified. + */ + UdevEnumerate udev_enumerate_ref(UdevEnumerate udev_enumerate); + + /** + * Drop a reference to a udev enumerate object. Once the reference count hits 0, + * the enumerate object is destroyed and freed. + * + * @param udev_enumerate + * A udev enumerate object. + * @return always returns NULL. + */ + UdevEnumerate udev_enumerate_unref(UdevEnumerate udev_enumerate); + + /** + * Modify filters of a udev enumerate object to match a subsystem. + * + * @param udev_enumerate + * The udev enumerate object to modify. + * @param subsystem + * The subsystem to match + * @return an integer greater than, or equal to, 0 on success. + */ + int udev_enumerate_add_match_subsystem(UdevEnumerate udev_enumerate, String subsystem); + + /** + * Query a udev enumerate object. Scans {@code /sys} for all devices which match + * the given filters. No matches will return all currently available devices. + * + * @param udev_enumerate + * The udev enumerate object, with optional filters. + * @return an integer greater than, or equal to, 0 on success. + */ + int udev_enumerate_scan_devices(UdevEnumerate udev_enumerate); + + /** + * Get the first list entry from a udev enumerate object. + * + * @param udev_enumerate + * The udev enumerate object. + * @return On success, returns a pointer to the first entry in the list of found + * devices. If the list is empty, or on failure, NULL is returned. + */ + UdevListEntry udev_enumerate_get_list_entry(UdevEnumerate udev_enumerate); + + /** + * Gets the next entry in the enumeration. + * + * @param list_entry + * the current list entry + * @return On success, returns a pointer to the next list entry. If no such + * entry can be found, or on failure, NULL is returned. + */ + UdevListEntry udev_list_entry_get_next(UdevListEntry list_entry); + + /** + * Get the name of the udev list entry + * + * @param list_entry + * A udev list entry + * @return a pointer to a constant string representing the requested value. The + * string is bound to the lifetime of the list entry itself. On failure, + * NULL is returned. + */ + String udev_list_entry_get_name(UdevListEntry list_entry); + + /** + * Acquire further references to a udev device object. + * + * @param udev_device + * A udev device object. + * @return the argument that was passed, unmodified. + */ + UdevDevice udev_device_ref(UdevDevice udev_device); + + /** + * Drop a reference to a udev device object. Once the reference count hits 0, + * the device object is destroyed and freed. + * + * @param udev_device + * A udev device object. + * @return always returns NULL. + */ + UdevDevice udev_device_unref(UdevDevice udev_device); + + /** + * Gets the parent of a udev device + * + * @param udev_device + * A udev device object. + * @return a pointer to the parent device. No additional reference to this + * device is acquired, but the child device owns a reference to such a + * parent device. On failure, NULL is returned. + */ + UdevDevice udev_device_get_parent(UdevDevice udev_device); + + /** + * Gets the parent of a udev device matching a subsystem and devtype + * + * @param udev_device + * A udev device object. + * @param subsystem + * The subsystem to match + * @param devtype + * The device type to match + * @return a pointer to the parent device. No additional reference to this + * device is acquired, but the child device owns a reference to such a + * parent device. On failure, NULL is returned. + */ + UdevDevice udev_device_get_parent_with_subsystem_devtype(UdevDevice udev_device, String subsystem, String devtype); + + /** + * Gets the syspath of a udev device + * + * @param udev_device + * A udev device object. + * @return a pointer to a constant string that describes the syspath. The + * lifetime of this string is bound to the device it was requested on. + * On failure, may return NULL. + */ + String udev_device_get_syspath(UdevDevice udev_device); + + /** + * Gets the sysname of a udev device + * + * @param udev_device + * A udev device object. + * @return a pointer to a constant string that describes the sysname. The + * lifetime of this string is bound to the device it was requested on. + * On failure, may return NULL. + */ + String udev_device_get_sysname(UdevDevice udev_device); + + /** + * Gets the devnode of a udev device + * + * @param udev_device + * A udev device object. + * @return a pointer to a constant string that describes the devnode. The + * lifetime of this string is bound to the device it was requested on. + * On failure, may return NULL. + */ + String udev_device_get_devnode(UdevDevice udev_device); + + /** + * Gets the devtype of a udev device + * + * @param udev_device + * A udev device object. + * @return a pointer to a constant string that describes the devtype. The + * lifetime of this string is bound to the device it was requested on. + * On failure, may return NULL. + */ + String udev_device_get_devtype(UdevDevice udev_device); + + /** + * Gets the subsystem of a udev device + * + * @param udev_device + * A udev device object. + * @return a pointer to a constant string that describes the subsystem. The + * lifetime of this string is bound to the device it was requested on. + * On failure, may return NULL. + */ + String udev_device_get_subsystem(UdevDevice udev_device); + + /** + * Retrieves a device attributesfrom a udev device. + * + * @param udev_device + * A udev device object. + * @param sysattr + * The attribute to retrieve. + * @return a pointer to a constant string of the requested value. On error, NULL + * is returned. Attributes that may contain NUL bytes should not be + * retrieved with udev_device_get_sysattr_value(); instead, read them + * directly from the files within the device's syspath. + */ + String udev_device_get_sysattr_value(UdevDevice udev_device, String sysattr); + + /** + * Retrieves a device property from a udev device. + * + * @param udev_device + * A udev device object. + * @param key + * The property to retrieve. + * @return a pointer to a constant string of the requested value. On error, NULL + * is returned. + */ + String udev_device_get_property_value(UdevDevice udev_device, String key); +} \ No newline at end of file diff --git a/contrib/platform/src/com/sun/jna/platform/unix/LibCAPI.java b/contrib/platform/src/com/sun/jna/platform/unix/LibCAPI.java index 27da5b7e6b..c2a9b9485e 100644 --- a/contrib/platform/src/com/sun/jna/platform/unix/LibCAPI.java +++ b/contrib/platform/src/com/sun/jna/platform/unix/LibCAPI.java @@ -23,6 +23,10 @@ */ package com.sun.jna.platform.unix; +import com.sun.jna.IntegerType; +import com.sun.jna.Native; +import com.sun.jna.Pointer; + /** * Note: we are using this "intermediate" API in order to allow * Linux-like O/S-es to implement the same API, but maybe using a different @@ -30,6 +34,42 @@ * @author Lyor Goldstein */ public interface LibCAPI extends Reboot, Resource { + + /** + * This is an unsigned integer type used to represent the sizes of objects. + */ + class size_t extends IntegerType { + public static final size_t ZERO = new size_t(); + + private static final long serialVersionUID = 1L; + + public size_t() { + this(0); + } + + public size_t(long value) { + super(Native.SIZE_T_SIZE, value, true); + } + } + + /** + * This is a signed integer type used for a count of bytes or an error + * indication. + */ + class ssize_t extends IntegerType { + public static final ssize_t ZERO = new ssize_t(); + + private static final long serialVersionUID = 1L; + + public ssize_t() { + this(0); + } + + public ssize_t(long value) { + super(Native.SIZE_T_SIZE, value, false); + } + } + // see man(2) get/set uid/gid int getuid(); int geteuid(); @@ -98,4 +138,68 @@ public interface LibCAPI extends Reboot, Resource { * @see getloadavg(3) */ int getloadavg(double[] loadavg, int nelem); + + /** + * Closes a file descriptor, so that it no longer refers to any file and may be + * reused. Any record locks held on the file it was associated with, and owned + * by the process, are removed (regardless of the file descriptor that was used + * to obtain the lock). + *
+ * If {@code fd} is the last file descriptor referring to the underlying open + * file description, the resources associated with the open file description are + * freed; if the file descriptor was the last reference to a file which has been + * removed using {@code unlink}, the file is deleted. + * + * @param fd + * a file descriptor + * @return returns zero on success. On error, -1 is returned, and {@code errno} + * is set appropriately. + *
+ * {@code close()} should not be retried after an error. + */ + int close(int fd); + + /** + * Flushes changes made to the in-core copy of a file that was mapped into + * memory using {@link LibCUtil#mmap(Pointer, long, int, int, int, long)} back + * to the filesystem. Without use of this call, there is no guarantee that + * changes are written back before {@link #munmap(Pointer, size_t)} is called. + * To be more precise, the part of the file that corresponds to the memory area + * starting at {@code addr} and having length {@code length} is updated. + * + * @param addr + * The start of the memory area to sync to the filesystem. + * @param length + * The length of the memory area to sync to the filesystem. + * @param flags + * The flags argument should specify exactly one of {@code MS_ASYNC} + * and {@code MS_SYNC}, and may additionally include the + * {@code MS_INVALIDATE} bit. + * @return On success, zero is returned. On error, -1 is returned, and + * {@code errno} is set appropriately. + */ + int msync(Pointer addr, size_t length, int flags); + + /** + * Deletes the mappings for the specified address range, and causes further + * references to addresses within the range to generate invalid memory + * references. The region is also automatically unmapped when the process is + * terminated. On the other hand, closing the file descriptor does not unmap the + * region. + *
+ * It is not an error if the indicated range does not contain any mapped pages. + * + * @param addr + * The base address from which to delete mappings. The address addr + * must be a multiple of the page size (but length need not be). + * @param length + * The length from the base address to delete mappings. All pages + * containing a part of the indicated range are unmapped, and + * subsequent references to these pages will generate + * {@code SIGSEGV}. + * @return On success, returns 0. On failure, it returns -1, and {@code errno} + * is set to indicate the cause of the error (probably to + * {@code EINVAL}). + */ + int munmap(Pointer addr, size_t length); } diff --git a/contrib/platform/src/com/sun/jna/platform/unix/LibCUtil.java b/contrib/platform/src/com/sun/jna/platform/unix/LibCUtil.java new file mode 100644 index 0000000000..36499834df --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/unix/LibCUtil.java @@ -0,0 +1,174 @@ +/* Copyright (c) 2020 Daniel Widdis, All Rights Reserved + * + * The contents of this file is dual-licensed under 2 + * alternative Open Source/Free licenses: LGPL 2.1 or later and + * Apache License 2.0. (starting with JNA version 4.0.0). + * + * You can freely decide which license you want to apply to + * the project. + * + * You may obtain a copy of the LGPL License at: + * + * http://www.gnu.org/licenses/licenses.html + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "LGPL2.1". + * + * You may obtain a copy of the Apache License at: + * + * http://www.apache.org/licenses/ + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "AL2.0". + */ +package com.sun.jna.platform.unix; + +import com.sun.jna.Function; +import com.sun.jna.Native; +import com.sun.jna.NativeLibrary; +import com.sun.jna.Pointer; + +/** + * Utility class supporting variable-width types in the C Library. Portable code + * should avoid using {@code off_t} because it is dependent upon features + * selected at compile-time. This class provides helper methods that safely + * avoid these types by using 64-bit mappings when available. + */ +public class LibCUtil { + + private static final NativeLibrary LIBC = NativeLibrary.getInstance("c"); + + private static Function mmap = null; + private static boolean mmap64 = false; + private static Function ftruncate = null; + private static boolean ftruncate64 = false; + static { + try { + mmap = LIBC.getFunction("mmap64", Function.THROW_LAST_ERROR); + mmap64 = true; + } catch (UnsatisfiedLinkError ex) { + mmap = LIBC.getFunction("mmap", Function.THROW_LAST_ERROR); + } + try { + ftruncate = LIBC.getFunction("ftruncate64", Function.THROW_LAST_ERROR); + ftruncate64 = true; + } catch (UnsatisfiedLinkError ex) { + ftruncate = LIBC.getFunction("ftruncate", Function.THROW_LAST_ERROR); + } + } + + private LibCUtil() { + } + + /** + * Creates a new mapping in the virtual address space of the calling process. + * + * @param addr + * The starting address for the new mapping. + *
+ * If {@code addr} is NULL, then the kernel chooses the + * (page-aligned) address at which to create the mapping; this is the + * most portable method of creating a new mapping. If {@code addr} is + * not NULL, then the kernel takes it as a hint about where to place + * the mapping; on Linux, the kernel will pick a nearby page boundary + * (but always above or equal to the value specified by + * {@code /proc/sys/vm/mmap_min_addr}) and attempt to create the + * mapping there. If another mapping already exists there, the kernel + * picks a new address that may or may not depend on the hint. The + * address of the new mapping is returned as the result of the call. + * @param length + * Specifies the length of the mapping (which must be greater than + * 0). + * @param prot + * describes the desired memory protection of the mapping (and must + * not conflict with the open mode of the file). It is either + * {@code PROT_NONE} or the bitwise OR of one or more of + * {@code PROT_READ}, {@code PROT_WRITE}, or {@code PROT_EXEC}. + * @param flags + * determines whether updates to the mapping are visible to other + * processes mapping the same region, and whether updates are carried + * through to the underlying file. This behavior is determined by + * including exactly one of {@code MAP_SHARED}, + * {@code MAP_SHARED_VALIDATE}, or {@code MAP_PRIVATE}. In addition, + * 0 or more additional flags can be ORed in {@code flags}. + * @param fd + * The file descriptor for the object to be mapped. After the + * {@code mmap()} call has returned, the file descriptor can be + * closed immediately without invalidating the mapping. + * @param offset + * The contents of a file mapping (as opposed to an anonymous + * mapping), are initialized using {@code length} bytes starting at + * offset {@code offset} in the file (or other object) referred to by + * the file descriptor, {@code fd}. {@code offset} must be a multiple + * of the page size as returned by {@code sysconf(_SC_PAGE_SIZE)}. + * @return On success, returns a pointer to the mapped area. On error, the value + * {@code MAP_FAILED} (that is, (void *) -1) is returned, and + * {@code errno} is set to indicate the cause of the error. + */ + public static Pointer mmap(Pointer addr, long length, int prot, int flags, int fd, long offset) { + Object[] params = new Object[6]; + params[0] = addr; + if (Native.SIZE_T_SIZE == 4) { + require32Bit(length, "length"); + params[1] = (int) length; + } else { + params[1] = length; + } + params[2] = prot; + params[3] = flags; + params[4] = fd; + if (mmap64 || Native.LONG_SIZE > 4) { + params[5] = offset; + } else { + require32Bit(offset, "offset"); + params[5] = (int) offset; + } + return mmap.invokePointer(params); + } + + /** + * Causes the regular file referenced by {@code fd} to be truncated to a size of + * precisely {@code length} bytes. + *
+ * If the file previously was larger than this size, the extra data is lost. If + * the file previously was shorter, it is extended, and the extended part reads + * as null bytes ('\0'). + *
+ * The file must be open for writing + * + * @param fd + * a file descriptor + * @param length + * the number of bytes to truncate or extend the file to + * @return On success, zero is returned. On error, -1 is returned, and + * {@code errno} is set appropriately. + */ + public static int ftruncate(int fd, long length) { + Object[] params = new Object[2]; + params[0] = fd; + if (ftruncate64 || Native.LONG_SIZE > 4) { + params[1] = length; + } else { + require32Bit(length, "length"); + params[1] = (int) length; + } + return ftruncate.invokeInt(params); + } + + /** + * Test that a value is 32-bit, throwing a custom exception otherwise + * + * @param val + * The value to test + * @param value + * The name of the value, to be inserted in the exception message if + * not 32-bit + * @throws IllegalArgumentException + * if {@code val} is not 32-bit + */ + public static void require32Bit(long val, String value) { + if (val > Integer.MAX_VALUE) { + throw new IllegalArgumentException(value + " exceeds 32bit"); + } + } +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/IPHlpAPI.java b/contrib/platform/src/com/sun/jna/platform/win32/IPHlpAPI.java index ac5cc5cfa4..2e6cf1e63e 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/IPHlpAPI.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/IPHlpAPI.java @@ -52,8 +52,13 @@ public interface IPHlpAPI extends Library { int MAX_SCOPE_ID_LEN = 256; // Source: Winsock2.h + int AF_UNSPEC = 0; // The address family is unspecified. int AF_INET = 2; // The Internet Protocol version 4 (IPv4) address family. + int AF_IPX = 6; // The IPX/SPX address family. + int AF_NETBIOS = 17; // The NetBIOS address family. int AF_INET6 = 23; // The Internet Protocol version 6 (IPv6) address family. + int AF_IRDA = 26; // The Infrared Data Association (IrDA) address family. + int AF_BTH = 32; // The Bluetooth address family. /** * The MIB_IFROW structure stores information about a particular interface. diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java index 7795269c0d..7b0b2dcb83 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java @@ -2385,6 +2385,37 @@ boolean DeviceIoControl(HANDLE hDevice, int dwIoControlCode, */ boolean Process32Next(HANDLE hSnapshot, Tlhelp32.PROCESSENTRY32 lppe); + /** + * Retrieves information about the first thread of any process encountered in a + * system snapshot. + * + * @param hSnapshot + * A handle to the snapshot returned from a previous call to the + * CreateToolhelp32Snapshot function. + * @param lpte + * A pointer to a THREADENTRY32 structure. + * @return Returns TRUE if the first entry of the thread list has been copied to + * the buffer or FALSE otherwise. The ERROR_NO_MORE_FILES error value is + * returned by the GetLastError function if no threads exist or the + * snapshot does not contain thread information. + */ + boolean Thread32First(HANDLE hSnapshot, Tlhelp32.THREADENTRY32 lpte); + + /** + * Retrieves information about the next process recorded in a system snapshot. + * + * @param hSnapshot + * A handle to the snapshot returned from a previous call to the + * CreateToolhelp32Snapshot function. + * @param lpte + * A pointer to a THREADENTRY32 structure. + * @return Returns TRUE if the next entry of the thread list has been copied to + * the buffer or FALSE otherwise. The ERROR_NO_MORE_FILES error value is + * returned by the GetLastError function if no threads exist or the + * snapshot does not contain thread information. + */ + boolean Thread32Next(HANDLE hSnapshot, Tlhelp32.THREADENTRY32 lpte); + /** * The SetEnvironmentVariable function sets the contents of the specified * environment variable for the current process. diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java index d4a5394e83..953bcc3c95 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java @@ -854,6 +854,49 @@ public static final String extractVolumeGUID(String volumeGUIDPath) { return volumeGUIDPath.substring(VOLUME_GUID_PATH_PREFIX.length(), volumeGUIDPath.length() - VOLUME_GUID_PATH_SUFFIX.length()); } + /** + * + * This function retrieves the full path of the executable file of a given process identifier. + * + * @param pid + * Identifier for the running process + * @param dwFlags + * 0 - The name should use the Win32 path format. + * 1(WinNT.PROCESS_NAME_NATIVE) - The name should use the native system path format. + * + * @return the full path of the process's executable file of null if failed. To get extended error information, + * call GetLastError. + */ + public static final String QueryFullProcessImageName(int pid, int dwFlags) { + HANDLE hProcess = null; + Win32Exception we = null; + + try { + hProcess = Kernel32.INSTANCE.OpenProcess(WinNT.PROCESS_QUERY_INFORMATION | WinNT.PROCESS_VM_READ, false, pid); + if (hProcess == null) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + return QueryFullProcessImageName(hProcess, dwFlags); + } catch (Win32Exception e) { + we = e; + throw we; // re-throw to invoke finally block + } finally { + try { + closeHandle(hProcess); + } catch (Win32Exception e) { + if (we == null) { + we = e; + } else { + we.addSuppressed(e); + } + } + if (we != null) { + throw we; + } + } + } + /** * * This function retrieves the full path of the executable file of a given process. @@ -868,10 +911,16 @@ public static final String extractVolumeGUID(String volumeGUIDPath) { * call GetLastError. */ public static final String QueryFullProcessImageName(HANDLE hProcess, int dwFlags) { - char[] path = new char[WinDef.MAX_PATH]; - IntByReference lpdwSize = new IntByReference(path.length); - if (Kernel32.INSTANCE.QueryFullProcessImageName(hProcess, 0, path, lpdwSize)) - return new String(path).substring(0, lpdwSize.getValue()); + int size = 0; + IntByReference lpdwSize = new IntByReference(); + do { + size = size + (size == 0 ? WinDef.MAX_PATH : 1024); // Start with MAX_PATH, then increment with 1024 each iteration + char[] lpExeName = new char[size]; + lpdwSize.setValue(size); + if (Kernel32.INSTANCE.QueryFullProcessImageName(hProcess, dwFlags, lpExeName, lpdwSize)) { + return new String(lpExeName, 0, lpdwSize.getValue()); + } + } while (Kernel32.INSTANCE.GetLastError() == Kernel32.ERROR_INSUFFICIENT_BUFFER); throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Netapi32.java b/contrib/platform/src/com/sun/jna/platform/win32/Netapi32.java index 907424bde1..588dc1cb4f 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Netapi32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Netapi32.java @@ -26,6 +26,8 @@ import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.Structure; +import com.sun.jna.Structure.FieldOrder; +import com.sun.jna.WString; import com.sun.jna.platform.win32.DsGetDC.PDOMAIN_CONTROLLER_INFO; import com.sun.jna.platform.win32.Guid.GUID; import com.sun.jna.platform.win32.NTSecApi.PLSA_FOREST_TRUST_INFORMATION; @@ -33,6 +35,7 @@ import com.sun.jna.ptr.PointerByReference; import com.sun.jna.win32.StdCallLibrary; import com.sun.jna.win32.W32APIOptions; +import com.sun.jna.win32.W32APITypeMapper; /** * Netapi32.dll Interface. @@ -42,6 +45,83 @@ public interface Netapi32 extends StdCallLibrary { Netapi32 INSTANCE = Native.load("Netapi32", Netapi32.class, W32APIOptions.DEFAULT_OPTIONS); + int MAX_PREFERRED_LENGTH = -1; + + /** + * Contains information about the session, including name of the computer; name + * of the user; and active and idle times for the session. + */ + @FieldOrder({ "sesi10_cname", "sesi10_username", "sesi10_time", "sesi10_idle_time" }) + class SESSION_INFO_10 extends Structure { + public String sesi10_cname; + public String sesi10_username; + public int sesi10_time; + public int sesi10_idle_time; + + public SESSION_INFO_10() { + super(W32APITypeMapper.UNICODE); + } + + public SESSION_INFO_10(Pointer p) { + super(p, Structure.ALIGN_DEFAULT, W32APITypeMapper.UNICODE); + read(); + } + } + + /** + * Provides information about sessions established on a server. + * + * @param servername + * Pointer to a string that specifies the DNS or NetBIOS name of the + * remote server on which the function is to execute. If this + * parameter is NULL, the local computer is used. + * @param UncClientName + * Pointer to a string that specifies the name of the computer + * session for which information is to be returned. If this parameter + * is NULL, NetSessionEnum returns information for all computer + * sessions on the server. + * @param username + * Pointer to a string that specifies the name of the user for which + * information is to be returned. If this parameter is NULL, + * NetSessionEnum returns information for all users. + * @param level + * Specifies the information level of the data. This parameter can be + * one of 0, 1, 2, 10, 502. + * @param bufptr + * Pointer to the buffer that receives the data. The format of this + * data depends on the value of the level parameter, for example + * {@code SESSION_INFO_0} for level 0. + *
+ * This buffer is allocated by the system and must be freed using the
+ * {@link #NetApiBufferFree} function. Note that you must free the
+ * buffer even if the function fails with {@code ERROR_MORE_DATA}.
+ * @param prefmaxlen
+ * Specifies the preferred maximum length of returned data, in bytes.
+ * If you specify {@link #MAX_PREFERRED_LENGTH}, the function
+ * allocates the amount of memory required for the data. If you
+ * specify another value in this parameter, it can restrict the
+ * number of bytes that the function returns. If the buffer size is
+ * insufficient to hold all entries, the function returns
+ * {@code ERROR_MORE_DATA}.
+ * @param entriesread
+ * Pointer to a value that receives the count of elements actually
+ * enumerated.
+ * @param totalentries
+ * Pointer to a value that receives the total number of entries that
+ * could have been enumerated from the current resume position. Note
+ * that applications should consider this value only as a hint.
+ * @param resume_handle
+ * Pointer to a value that contains a resume handle which is used to
+ * continue an existing session search. The handle should be zero on
+ * the first call and left unchanged for subsequent calls. If
+ * resume_handle is NULL, no resume handle is stored.
+ * @return If the function succeeds, the return value is NERR_Success (0). If
+ * the function fails, the return value is an error code.
+ */
+ int NetSessionEnum(WString servername, WString UncClientName, WString username, int level,
+ PointerByReference bufptr, int prefmaxlen, IntByReference entriesread, IntByReference totalentries,
+ IntByReference resume_handle);
+
/**
* Retrieves join status information for the specified computer.
*
diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Psapi.java b/contrib/platform/src/com/sun/jna/platform/win32/Psapi.java
index c6c89c5180..b071617531 100644
--- a/contrib/platform/src/com/sun/jna/platform/win32/Psapi.java
+++ b/contrib/platform/src/com/sun/jna/platform/win32/Psapi.java
@@ -266,6 +266,46 @@ public interface Psapi extends StdCallLibrary {
*/
boolean GetPerformanceInfo(PERFORMANCE_INFORMATION pPerformanceInformation, int cb);
+ /**
+ * Retrieves the process identifier for each process object in the system.
+ *
+ * It is a good idea to use a large array, because it is hard to predict
+ * how many processes there will be at the time you call EnumProcesses.
+ *
+ * To determine how many processes were enumerated, divide the
+ * pBytesReturned value by sizeof(DWORD). There is no indication given
+ * when the buffer is too small to store all process identifiers.
+ * Therefore, if pBytesReturned equals cb, consider retrying the call
+ * with a larger array.
+ *
+ * To obtain process handles for the processes whose identifiers you
+ * have just obtained, call the OpenProcess function.
+ *
+ * Starting with Windows 7 and Windows Server 2008 R2, Psapi.h
+ * establishes version numbers for the PSAPI functions. The PSAPI
+ * version number affects the name used to call the function and the
+ * library that a program must load.
+ *
+ * If PSAPI_VERSION is 2 or greater, this function is defined as
+ * K32EnumProcesses in Psapi.h and exported in Kernel32.lib and
+ * Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as
+ * EnumProcesses in Psapi.h and exported in Psapi.lib and Psapi.dll as a
+ * wrapper that calls K32EnumProcesses.
+ *
+ * @param lpidProcess
+ * A pointer to an array that receives the list of process
+ * identifiers
+ * @param cb
+ * The size of the pProcessIds array, in bytes.
+ * @param lpcbNeeded
+ * The number of bytes returned in the pProcessIds array.
+ * @return If the function succeeds, the return value is nonzero. If the
+ * function fails, the return value is zero. To get extended
+ * error information, call GetLastError.
+ * @see MSDN
+ */
+ boolean EnumProcesses(int[] lpidProcess, int cb, IntByReference lpcbNeeded);
+
@FieldOrder({"lpBaseOfDll", "SizeOfImage", "EntryPoint"})
class MODULEINFO extends Structure {
public Pointer EntryPoint;
diff --git a/contrib/platform/src/com/sun/jna/platform/win32/PsapiUtil.java b/contrib/platform/src/com/sun/jna/platform/win32/PsapiUtil.java
new file mode 100644
index 0000000000..cba11f9843
--- /dev/null
+++ b/contrib/platform/src/com/sun/jna/platform/win32/PsapiUtil.java
@@ -0,0 +1,57 @@
+/* Copyright (c) 2020 Torbjörn Svensson, All Rights Reserved
+ *
+ * The contents of this file is dual-licensed under 2
+ * alternative Open Source/Free licenses: LGPL 2.1 or later and
+ * Apache License 2.0. (starting with JNA version 4.0.0).
+ *
+ * You can freely decide which license you want to apply to
+ * the project.
+ *
+ * You may obtain a copy of the LGPL License at:
+ *
+ * http://www.gnu.org/licenses/licenses.html
+ *
+ * A copy is also included in the downloadable source code package
+ * containing JNA, in file "LGPL2.1".
+ *
+ * You may obtain a copy of the Apache License at:
+ *
+ * http://www.apache.org/licenses/
+ *
+ * A copy is also included in the downloadable source code package
+ * containing JNA, in file "AL2.0".
+ */
+package com.sun.jna.platform.win32;
+
+import java.util.Arrays;
+
+import com.sun.jna.platform.win32.WinDef.DWORD;
+import com.sun.jna.ptr.IntByReference;
+
+/**
+ * Psapi utility API.
+ *
+ * @author Torbjörn Svensson, azoff[at]svenskalinuxforeninen.se
+ */
+public abstract class PsapiUtil {
+
+ /**
+ * Retrieves the process identifier for each process object in the system.
+ *
+ * @return Array of pids
+ */
+ public static int[] enumProcesses() {
+ int size = 0;
+ int[] lpidProcess = null;
+ IntByReference lpcbNeeded = new IntByReference();
+ do {
+ size = size + 1024;
+ lpidProcess = new int[size];
+ if (!Psapi.INSTANCE.EnumProcesses(lpidProcess, size * DWORD.SIZE, lpcbNeeded)) {
+ throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
+ }
+ } while (size == lpcbNeeded.getValue() / DWORD.SIZE);
+
+ return Arrays.copyOf(lpidProcess, lpcbNeeded.getValue() / DWORD.SIZE);
+ }
+}
diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Tlhelp32.java b/contrib/platform/src/com/sun/jna/platform/win32/Tlhelp32.java
index 607ddcb409..6c72b02bd6 100644
--- a/contrib/platform/src/com/sun/jna/platform/win32/Tlhelp32.java
+++ b/contrib/platform/src/com/sun/jna/platform/win32/Tlhelp32.java
@@ -22,9 +22,8 @@
*/
package com.sun.jna.platform.win32;
-import java.util.List;
-
import com.sun.jna.Native;
+import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.Structure.FieldOrder;
@@ -171,11 +170,78 @@ public PROCESSENTRY32(Pointer memory) {
}
}
+ /**
+ * Describes an entry from a list of the threads executing in the system when a
+ * snapshot was taken.
+ */
+ @FieldOrder({ "dwSize", "cntUsage", "th32ThreadID", "th32OwnerProcessID", "tpBasePri", "tpDeltaPri", "dwFlags" })
+ public static class THREADENTRY32 extends Structure {
+
+ public static class ByReference extends THREADENTRY32 implements Structure.ByReference {
+ public ByReference() {
+ }
+
+ public ByReference(Pointer memory) {
+ super(memory);
+ }
+ }
+
+ /**
+ * The size of the structure, in bytes. Before calling the Thread32First
+ * function, set this member to sizeof(THREADENTRY32). If you do not initialize
+ * dwSize, Thread32First fails.
+ */
+ int dwSize;
+
+ /**
+ * This member is no longer used and is always set to zero.
+ */
+ int cntUsage;
+
+ /**
+ * The thread identifier, compatible with the thread identifier returned by the
+ * CreateProcess function.
+ */
+ int th32ThreadID;
+
+ /**
+ * The identifier of the process that created the thread.
+ */
+ int th32OwnerProcessID;
+
+ /**
+ * The kernel base priority level assigned to the thread. The priority is a
+ * number from 0 to 31, with 0 representing the lowest possible thread priority.
+ * For more information, see KeQueryPriorityThread.
+ */
+ NativeLong tpBasePri;
+
+ /**
+ * This member is no longer used and is always set to zero.
+ */
+ NativeLong tpDeltaPri;
+
+ /**
+ * This member is no longer used and is always set to zero.
+ */
+ int dwFlags;
+
+ public THREADENTRY32() {
+ dwSize = size();
+ }
+
+ public THREADENTRY32(Pointer memory) {
+ super(memory);
+ read();
+ }
+ }
+
/**
* Describes an entry from a list of the modules belonging to the specified
* process.
*
- * @see MSDN
+ * @see MSDN
*/
@FieldOrder({"dwSize", "th32ModuleID", "th32ProcessID", "GlblcntUsage",
"ProccntUsage", "modBaseAddr", "modBaseSize", "hModule",
diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Wtsapi32.java b/contrib/platform/src/com/sun/jna/platform/win32/Wtsapi32.java
index 0f34d03d05..94af3c8bbd 100644
--- a/contrib/platform/src/com/sun/jna/platform/win32/Wtsapi32.java
+++ b/contrib/platform/src/com/sun/jna/platform/win32/Wtsapi32.java
@@ -113,11 +113,192 @@ public interface Wtsapi32 extends StdCallLibrary {
int WTS_PROCESS_INFO_LEVEL_0 = 0;
int WTS_PROCESS_INFO_LEVEL_1 = 1;
+ /**
+ * Defined in {@code winsta.h} and present in this interface to properly size
+ * the {@link WTSINFO} structure.
+ */
+ int DOMAIN_LENGTH = 17;
+
+ /**
+ * Defined in {@code winsta.h} and present in this interface to properly size
+ * the {@link WTSINFO} structure.
+ */
+ int USERNAME_LENGTH = 20;
+
+ /**
+ * Defined in {@code winsta.h} and present in this interface to properly size
+ * the {@link WTSINFO} structure.
+ */
+ int WINSTATIONNAME_LENGTH = 32;
+
+ /**
+ * Specifies the connection state of a Remote Desktop Services session.
+ */
+ public interface WTS_CONNECTSTATE_CLASS {
+ int WTSActive = 0;
+ int WTSConnected = 1;
+ int WTSConnectQuery = 2;
+ int WTSShadow = 3;
+ int WTSDisconnected = 4;
+ int WTSIdle = 5;
+ int WTSListen = 6;
+ int WTSReset = 7;
+ int WTSDown = 8;
+ int WTSInit = 9;
+ }
+
+ /**
+ * Contains values that indicate the type of session information to retrieve in
+ * a call to the {@link #WTSQuerySessionInformation()} function.
+ */
+ public interface WTS_INFO_CLASS {
+ int WTSInitialProgram = 0;
+ int WTSApplicationName = 1;
+ int WTSWorkingDirectory = 2;
+ int WTSOEMId = 3;
+ int WTSSessionId = 4;
+ int WTSUserName = 5;
+ int WTSWinStationName = 6;
+ int WTSDomainName = 7;
+ int WTSConnectState = 8;
+ int WTSClientBuildNumber = 9;
+ int WTSClientName = 10;
+ int WTSClientDirectory = 11;
+ int WTSClientProductId = 12;
+ int WTSClientHardwareId = 13;
+ int WTSClientAddress = 14;
+ int WTSClientDisplay = 15;
+ int WTSClientProtocolType = 16;
+ int WTSIdleTime = 17;
+ int WTSLogonTime = 18;
+ int WTSIncomingBytes = 19;
+ int WTSOutgoingBytes = 20;
+ int WTSIncomingFrames = 21;
+ int WTSOutgoingFrames = 22;
+ int WTSClientInfo = 23;
+ int WTSSessionInfo = 24;
+ int WTSSessionInfoEx = 25;
+ int WTSConfigInfo = 26;
+ int WTSValidationInfo = 27;
+ int WTSSessionAddressV4 = 28;
+ int WTSIsRemoteSession = 29;
+ }
+
+ /**
+ * Contains information about a client session on a Remote Desktop Session Host
+ * (RD Session Host) server.
+ */
+ @FieldOrder({ "SessionId", "pWinStationName", "State" })
+ class WTS_SESSION_INFO extends Structure {
+ public int SessionId;
+ public String pWinStationName; // either LPSTR or LPWSTR
+ public int State; // WTS_CONNECTSTATE_CLASS
+
+ public WTS_SESSION_INFO() {
+ super(W32APITypeMapper.DEFAULT);
+ }
+
+ public WTS_SESSION_INFO(Pointer p) {
+ super(p, Structure.ALIGN_DEFAULT, W32APITypeMapper.DEFAULT);
+ read();
+ }
+ }
+
+ /**
+ * Contains the client network address of a Remote Desktop Services session.
+ */
+ @FieldOrder({ "AddressFamily", "Address" })
+ class WTS_CLIENT_ADDRESS extends Structure {
+ public int AddressFamily;
+ public byte[] Address = new byte[20];
+
+ public WTS_CLIENT_ADDRESS() {
+ super();
+ }
+
+ public WTS_CLIENT_ADDRESS(Pointer p) {
+ super(p);
+ read();
+ }
+ }
+
+ /**
+ * Contains information about a Remote Desktop Services session.
+ */
+ @FieldOrder({ "State", "SessionId", "IncomingBytes", "OutgoingBytes", "IncomingFrames", "OutgoingFrames",
+ "IncomingCompressedBytes", "OutgoingCompressedBytes", "WinStationName", "Domain", "UserName", "ConnectTime",
+ "DisconnectTime", "LastInputTime", "LogonTime", "CurrentTime" })
+ class WTSINFO extends Structure {
+ private static final int CHAR_WIDTH = Boolean.getBoolean("w32.ascii") ? 1 : 2;
+
+ public int State; // WTS_CONNECTSTATE_CLASS
+ public int SessionId;
+ public int IncomingBytes;
+ public int OutgoingBytes;
+ public int IncomingFrames;
+ public int OutgoingFrames;
+ public int IncomingCompressedBytes;
+ public int OutgoingCompressedBytes;
+ public final byte[] WinStationName = new byte[WINSTATIONNAME_LENGTH * CHAR_WIDTH];
+ public final byte[] Domain = new byte[DOMAIN_LENGTH * CHAR_WIDTH];
+ public final byte[] UserName = new byte[(USERNAME_LENGTH + 1) * CHAR_WIDTH];
+ public LARGE_INTEGER ConnectTime;
+ public LARGE_INTEGER DisconnectTime;
+ public LARGE_INTEGER LastInputTime;
+ public LARGE_INTEGER LogonTime;
+ public LARGE_INTEGER CurrentTime;
+
+ public WTSINFO() {
+ super();
+ }
+
+ public WTSINFO(Pointer p) {
+ super(p);
+ read();
+ }
+
+ /**
+ * Convenience method to return the null-terminated string in the
+ * {@link #WinStationName} member, accounting for {@code CHAR} or {@code WCHAR}
+ * byte width.
+ *
+ * @return The {@code WinStationName} as a string.
+ */
+ public String getWinStationName() {
+ return getStringAtOffset(fieldOffset("WinStationName"));
+ }
+
+ /**
+ * Convenience method to return the null-terminated string in the
+ * {@link #Domain} member, accounting for {@code CHAR} or {@code WCHAR} byte
+ * width.
+ *
+ * @return The {@code Domain} as a string.
+ */
+ public String getDomain() {
+ return getStringAtOffset(fieldOffset("Domain"));
+ }
+
+ /**
+ * Convenience method to return the null-terminated string in the
+ * {@link #UserName} member, accounting for {@code CHAR} or {@code WCHAR} byte
+ * width.
+ *
+ * @return The {@code UserName} as a string.
+ */
+ public String getUserName() {
+ return getStringAtOffset(fieldOffset("UserName"));
+ }
+
+ private String getStringAtOffset(int offset) {
+ return CHAR_WIDTH == 1 ? getPointer().getString(offset) : getPointer().getWideString(offset);
+ }
+ }
+
/**
* Contains extended information about a process running on a Remote Desktop
* Session Host (RD Session Host) server. This structure is returned by the
- * WTSEnumerateProcessesEx function when you set the pLevel parameter to
- * one.
+ * WTSEnumerateProcessesEx function when you set the pLevel parameter to one.
*
* @see WTS_PROCESS_INFO_EXA
@@ -150,6 +331,92 @@ public WTS_PROCESS_INFO_EX(Pointer p) {
}
}
+ /**
+ * Retrieves a list of sessions on a Remote Desktop Session Host (RD Session
+ * Host) server.
+ *
+ * @param hServer
+ * A handle to the RD Session Host server.
+ *
+ * You can use the {@code WTSOpenServer} or {@code WTSOpenServerEx} + * functions to retrieve a handle to a specific server, or + * {@link #WTS_CURRENT_SERVER_HANDLE} to use the RD Session Host + * server that hosts your application. + * @param Reserved + * This parameter is reserved. It must be zero. + * @param Version + * The version of the enumeration request. This parameter must be 1. + * @param ppSessionInfo + * A pointer to an array of {@link WTS_SESSION_INFO} structures that + * represent the retrieved sessions. To free the returned buffer, + * call the {@link Wtsapi32#WTSFreeMemory} function. + * @param pCount + * A pointer to the number of {@code WTS_SESSION_INFO} structures + * returned in the {@code ppSessionInfo} parameter. + * @return Returns {@code false} if this function fails. If this function + * succeeds, returns {@code true}. + *
+ * To get extended error information, call + * {@link Kernel32#GetLastError()}. + */ + boolean WTSEnumerateSessions(HANDLE hServer, int Reserved, int Version, PointerByReference ppSessionInfo, + IntByReference pCount); + + /** + * Retrieves session information for the specified session on the specified + * Remote Desktop Session Host (RD Session Host) server. It can be used to query + * session information on local and remote RD Session Host servers. + * + * @param hServer + * A handle to an RD Session Host server. Specify a handle opened by + * the {@code WTSOpenServer} function, or specify + * {@link #WTS_CURRENT_SERVER_HANDLE} to indicate the RD Session Host + * server on which your application is running. + * @param SessionId + * A Remote Desktop Services session identifier. To indicate the + * session in which the calling application is running (or the + * current session) specify {@link #WTS_CURRENT_SESSION}. Only + * specify {@code WTS_CURRENT_SESSION} when obtaining session + * information on the local server. If {@code WTS_CURRENT_SESSION} is + * specified when querying session information on a remote server, + * the returned session information will be inconsistent. Do not use + * the returned data. + *
+ * You can use the {@code WTSEnumerateSessionsEx} function to + * retrieve the identifiers of all sessions on a specified RD Session + * Host server. + *
+ * To query information for another user's session, you must have + * Query Information permission. + * @param WTSInfoClass + * A value of the {@link WTS_INFO_CLASS} enumeration that indicates + * the type of session information to retrieve in a call to the + * {@code WTSQuerySessionInformation} function. + * @param ppBuffer + * A pointer to a variable that receives a pointer to the requested + * information. The format and contents of the data depend on the + * information class specified in the {@code WTSInfoClass} parameter. + * To free the returned buffer, call the {@link #WTSFreeMemory} + * function. + * @param pBytesReturned + * A pointer to a variable that receives the size, in bytes, of the + * data returned in ppBuffer. + * @return If the function succeeds, returns {@code true}. + *
+ * If the function fails, returns {@code false}. To get extended error
+ * information, call {@link Kernel32#GetLastError()}.
+ */
+ boolean WTSQuerySessionInformation(HANDLE hServer, int SessionId, int WTSInfoClass, PointerByReference ppBuffer,
+ IntByReference pBytesReturned);
+
+ /**
+ * Frees memory allocated by a Remote Desktop Services function.
+ *
+ * @param pMemory
+ * Pointer to the memory to free.
+ */
+ void WTSFreeMemory(Pointer pMemory);
+
/**
* Registers the specified window to receive session change notifications.
*
diff --git a/contrib/platform/test/com/sun/jna/platform/linux/LibCTest.java b/contrib/platform/test/com/sun/jna/platform/linux/LibCTest.java
index 1210bb30c7..50a3c661b1 100644
--- a/contrib/platform/test/com/sun/jna/platform/linux/LibCTest.java
+++ b/contrib/platform/test/com/sun/jna/platform/linux/LibCTest.java
@@ -23,20 +23,18 @@
*/
package com.sun.jna.platform.linux;
-import com.sun.jna.Native;
-import java.io.BufferedReader;
import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.List;
+import java.nio.file.FileStore;
+import java.nio.file.Files;
+import java.nio.file.Paths;
import org.junit.Test;
+import com.sun.jna.Native;
import com.sun.jna.platform.linux.LibC.Statvfs;
import com.sun.jna.platform.linux.LibC.Sysinfo;
-import java.nio.file.FileStore;
-import java.nio.file.Files;
-import java.nio.file.Paths;
+import com.sun.jna.platform.unix.LibCAPI.size_t;
+import com.sun.jna.platform.unix.LibCAPI.ssize_t;
import junit.framework.TestCase;
@@ -45,6 +43,15 @@
*/
public class LibCTest extends TestCase {
+ @Test
+ public void testSizeTypes() {
+ long VALUE = 20;
+ size_t st = new size_t(VALUE);
+ assertEquals("Wrong size_t value", VALUE, st.longValue());
+ ssize_t sst = new ssize_t(VALUE);
+ assertEquals("Wrong ssize_t value", VALUE, sst.longValue());
+ }
+
@Test
public void testSysinfo() {
Sysinfo info = new Sysinfo();
@@ -76,24 +83,9 @@ public void testStatvfs() throws IOException, InterruptedException {
FileStore fstore = Files.getFileStore(Paths.get(testDirectory));
assertEquals(fstore.getTotalSpace(), vfs.f_blocks.longValue() * vfs.f_bsize.longValue());
- assertEquals(fstore.getUsableSpace(), vfs.f_bavail.longValue() * vfs.f_bsize.longValue());
assertTrue(vfs.f_bsize.longValue() > 0);
assertTrue(vfs.f_bfree.longValue() <= vfs.f_blocks.longValue());
assertTrue(vfs.f_ffree.longValue() <= vfs.f_files.longValue());
assertTrue(vfs.f_namemax.longValue() > 0);
}
-
- private static List