From 8500058d1aeac527b46222ff59071b11b9dc8fda Mon Sep 17 00:00:00 2001
From: JaniruTEC
+Windows Data Types/Mapped C Data Types: [Web](https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types) | [Permalink](https://web.archive.org/web/20200616152122/https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types)
+JNA Data Types: [Web](https://java-native-access.github.io/jna/4.2.1/com/sun/jna/platform/win32/WinDef.html) | [Permalink](https://web.archive.org/web/20200616153134/http://java-native-access.github.io/jna/4.2.1/com/sun/jna/platform/win32/WinDef.html)
\ No newline at end of file
From 84bbb920391f65ae95af1cd24f61fdcc186a2148 Mon Sep 17 00:00:00 2001
From: JaniruTEC
Note that in two's complement arithmetic, the three other
+ * basic arithmetic operations of add, subtract, and multiply are
+ * bit-wise identical if the two operands are regarded as both
+ * being signed or both being unsigned. Therefore separate {@code
+ * addUnsigned}, etc. methods are not provided.
+ *
+ * @param dividend the value to be divided
+ * @param divisor the value doing the dividing
+ * @return the unsigned quotient of the first argument divided by
+ * the second argument
+ * @see #remainderUnsigned
+ * @since 1.8
+ *
+ * @see Integer#divideUnsigned(int, int)
+ */
+ public static @Unsigned byte divideUnsigned(@Unsigned byte dividend, @Unsigned byte divisor) {
+ return (byte) (Byte.toUnsignedInt(dividend) / Byte.toUnsignedInt(divisor));
+ }
+
+ /**
+ * Convenience method that stands in for the missing method {@code Short#divideUnsigned(short, short)}.
+ * This method was inspired by {@link Integer#divideUnsigned(int, int) the method of the same in Integer}
+ *
+ * Description copied from {@link Integer#divideUnsigned(int, int)}
+ * Returns the unsigned quotient of dividing the first argument by
+ * the second where each argument and the result is interpreted as
+ * an unsigned value.
+ *
+ *
Note that in two's complement arithmetic, the three other
+ * basic arithmetic operations of add, subtract, and multiply are
+ * bit-wise identical if the two operands are regarded as both
+ * being signed or both being unsigned. Therefore separate {@code
+ * addUnsigned}, etc. methods are not provided.
+ *
+ * @param dividend the value to be divided
+ * @param divisor the value doing the dividing
+ * @return the unsigned quotient of the first argument divided by
+ * the second argument
+ * @see #remainderUnsigned
+ * @since 1.8
+ *
+ * @see Integer#divideUnsigned(int, int)
+ */
+ public static @Unsigned short divideUnsigned(@Unsigned short dividend, @Unsigned short divisor) {
+ return (short) (Short.toUnsignedInt(dividend) / Short.toUnsignedInt(divisor));
+ }
+
+ /**
+ * Convenience method that delegates to {@link Integer#divideUnsigned(int, int)}.
+ *
+ * Description copied from {@link Integer#divideUnsigned(int, int)}
+ * Returns the unsigned quotient of dividing the first argument by
+ * the second where each argument and the result is interpreted as
+ * an unsigned value.
+ *
+ *
Note that in two's complement arithmetic, the three other
+ * basic arithmetic operations of add, subtract, and multiply are
+ * bit-wise identical if the two operands are regarded as both
+ * being signed or both being unsigned. Therefore separate {@code
+ * addUnsigned}, etc. methods are not provided.
+ *
+ * @param dividend the value to be divided
+ * @param divisor the value doing the dividing
+ * @return the unsigned quotient of the first argument divided by
+ * the second argument
+ * @see #remainderUnsigned
+ * @since 1.8
+ *
+ * @see Integer#divideUnsigned(int, int)
+ */
+ public static @Unsigned int divideUnsigned(@Unsigned int dividend, @Unsigned int divisor) {
+ return Integer.divideUnsigned(dividend, divisor);
+ }
+
+ /**
+ * Convenience method that delegates to {@link Long#divideUnsigned(long, long)}.
+ *
+ * Description copied from {@link Long#divideUnsigned(long, long)}
+ * Returns the unsigned quotient of dividing the first argument by
+ * the second where each argument and the result is interpreted as
+ * an unsigned value.
+ *
+ *
Note that in two's complement arithmetic, the three other
+ * basic arithmetic operations of add, subtract, and multiply are
+ * bit-wise identical if the two operands are regarded as both
+ * being signed or both being unsigned. Therefore separate {@code
+ * addUnsigned}, etc. methods are not provided.
+ *
+ * @param dividend the value to be divided
+ * @param divisor the value doing the dividing
+ * @return the unsigned quotient of the first argument divided by
+ * the second argument
+ * @see #remainderUnsigned
+ * @since 1.8
+ *
+ * @see Long#divideUnsigned(long, long)
+ */
+ public static @Unsigned long divideUnsigned(@Unsigned long dividend, @Unsigned long divisor) {
+ return Long.divideUnsigned(dividend, divisor);
+ }
+
+ public static @Unsigned byte remainderUnsigned(@Unsigned byte dividend, @Unsigned byte divisor) {
+ return (byte) (Byte.toUnsignedInt(dividend) % Byte.toUnsignedInt(divisor));
+ }
+
+ public static @Unsigned short remainderUnsigned(@Unsigned short dividend, @Unsigned short divisor) {
+ return (short) (Short.toUnsignedInt(dividend) % Short.toUnsignedInt(divisor));
+ }
+
+ public static @Unsigned int remainderUnsigned(@Unsigned int dividend, @Unsigned int divisor) {
+ return Integer.remainderUnsigned(dividend, divisor);
+ }
+
+ public static @Unsigned long remainderUnsigned(@Unsigned long dividend, @Unsigned long divisor) {
+ return Long.remainderUnsigned(dividend, divisor);
+ }
+
+ public static int compareUnsigned(byte x, byte y) {
+ return Byte.compareUnsigned(x, y);
+ }
+
+ public static int compareUnsigned(short x, short y) {
+ return Short.compareUnsigned(x, y);
+ }
+
+ public static int compareUnsigned(int x, int y) {
+ return Integer.compareUnsigned(x, y);
+ }
+
+ public static int compareUnsigned(long x, long y) {
+ return Long.compareUnsigned(x, y);
+ }
}
\ No newline at end of file
From 236347d571cab031b63ad916d4d906bc998d289f Mon Sep 17 00:00:00 2001
From: JaniruTEC
- * This implementation guarantees the existence of a SACL if SP-flag is set by only writing the flag if this strucutre is present.
+ * This implementation guarantees the existence of a SACL if SP-flag is set by only writing the flag if this structure is present.
*/
private Optional
- * This implementation guarantees the existence of a DACL if DP-flag is set by only writing the flag if this strucutre is present.
+ * This implementation guarantees the existence of a DACL if DP-flag is set by only writing the flag if this structure is present.
*/
private Optional
+ * Creates a java {@link List} of {@link DokanControl} structures given the pointer returned by NativeMethods#DokanGetMountPointList(boolean, LongByReference).
*
* Implementation note:
* Length is an unsigned 32-bit int. Java only supports arrays and lists up to an index size of 231-1 ({@link Integer#MAX_VALUE Integer.MAX_VALUE}).
diff --git a/src/main/java/dev/dokan/dokan_java/structure/filesecurity/AccessControlList.java b/src/main/java/dev/dokan/dokan_java/structure/filesecurity/AccessControlList.java
index e5f39c3..ef3e8e3 100644
--- a/src/main/java/dev/dokan/dokan_java/structure/filesecurity/AccessControlList.java
+++ b/src/main/java/dev/dokan/dokan_java/structure/filesecurity/AccessControlList.java
@@ -8,7 +8,7 @@
import java.util.List;
/**
- * Objectoriented implementation of the ACL-structure used in a {@link SelfRelativeSecurityDescriptor}.
+ * Object-oriented implementation of the ACL-structure used in a {@link SelfRelativeSecurityDescriptor}.
* For more information, please read the official Microsoft documentation.
*/
public class AccessControlList implements Byteable {
@@ -55,7 +55,7 @@ private enum ACLType {
private final short sbz2 = 0;
/**
- * List of AccessControlEntrys in this ACL
+ * List of AccessControlEntries in this ACL
*/
private List
+ * In this case integers are numbers without positions after decimal point.
+ * (Java's Default integer types being {@code byte, short, int, long} and their corresponding wrappers.)
+ * Introduction
+ * Java stores integer types in Two's complement-Representation.
+ * Usually numbers represented as Two's complement use the Most-Significant-Bit (MSB) to store the sign of the number.
+ * If a field is annotated with @Unsigned this rule does not apply!
+ * Instead the MSB should be considered as part of the number itself, resulting in a doubled storage capacity of the field
+ * while removing the support for signed values (the field becomes unsigned and the value should only be interpreted as positive.)
+ * See this table as reference for the resulting differences when interpreting numbers:
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * Signed value (Java Default)
+ * Unsigned values (@Unsigned)
+ * Bitmask (for a byte)
+ *
+ *
+ * 0
+ * 0
+ * 0000 0000
+ *
+ *
+ * 1
+ * 1
+ * 0000 0001
+ *
+ *
+ * 2
+ * 2
+ * 0000 0010
+ *
+ *
+ * 64
+ * 64
+ * 0100 0000
+ *
+ *
+ * -128
+ * 128
+ * 1000 0000
+ *
+ *
+ * -127
+ * 129
+ * 1000 0001
+ *
+ *
+ *
+ * -1
+ * 255
+ * 1111 1111
+ * Usage
+ * As Java only supports signed numbers, the correct interpretation and handling of unsigned numbers must be dealt with by the developer.
+ * Because of this it's strongly recommended to tag all values that are unsigned as such by using this annotation.
+ * @Unsigned is defined to {@link Target target} {@link java.lang.annotation.ElementType#TYPE_PARAMETER} and
+ * {@link java.lang.annotation.ElementType#TYPE_USE} and can therefore be applied to all usages of types (type contexts)
+ * and parameterized types respectively. See §9.6.4.1
+ * and §4.11 of "The Java® Language Specification" for
+ * further reference.
+ *
+ * At least the following cases ("minimum usage") should be annotated with @Unsigned to
+ * guarantee the best quality of code:
+ *
+ *
+ * Additionally it's recommended to annotate any other usage of unsigned types ("advanced usage"),
+ * especially (but not limited to):
+ *
+ *
+ * Note: Contributions to the dokan-java project must annotate all usages of unsigned types (Minimum usage and advanced usage)
+ * with @Unsigned.
+ * Pitfalls
+ * If a field is annotated with @Unsigned developers should take extra care handling it as some unsafe operations may lead
+ * to unexpected results.
+ * An operation is considered safe if using it with unsigned values yields the same results as using it with signed numbers.
+ * ("An operation is safe if it can be used the same way when dealing with unsigned values as one would use it with signed numbers.")
+ * The following (inconclusive) table shows which operations are safe or unsafe and how operations can be dealt with alternatively.
+ *
+ *
+ *
+ * Note: Operations that require two numbers (e.g. addition, subtraction) should never be used with a signed
+ * and an unsigned number as arguments, even if the operation is usually considered safe.
+ * Doing so can result in heavy computational errors, as seen here:
+ *
+ *
+ *
+ * Operation
+ * Safe/Unsafe
+ * Recommended course of action
+ *
+ *
+ * Adding (+)
+ * Safe
+ *
+ *
+ *
+ * Subtracting (-)
+ * Safe
+ *
+ *
+ *
+ * Multiplication (*)
+ * Safe
+ *
+ *
+ *
+ * Division (/)
+ * Unsafe
+ * {@link UnsignedNumbers#divideUnsigned(int, int)}
+ *
+ *
+ * Remainder/Modulo
+ * Unsafe
+ * {@link UnsignedNumbers#remainderUnsigned(int, int)}
+ *
+ *
+ * Comparision (%)
+ * Unsafe
+ * {@link UnsignedNumbers#compareUnsigned(int, int)}
+ *
+ *
+ * Printing
+ * Unsafe
+ * {@link UnsignedNumbers#toUnsignedString(int)}
+ *
+ *
+ * Downcasting
+ * Safe
+ * {@link UnsignedNumbers#toUnsignedInt(long)}
+ *
+ *
+ *
+ * Upcasting
+ * Unsafe
+ * {@link UnsignedNumbers#toUnsignedInt(short)}
+ *
+ *
+ * {@code //Don't do this:}
+ * {@code byte a = 64; //0100 0000}
+ * {@code @Unsigned byte b = 64; //0100 0000}
+ * {@code byte c = a + b; //0100 0000 + 0100 0000}
+ * {@code //--> c = -128; //1000 0000}
+ *
+ * This is a problem for the following reason: Before the addition the status (signed/unsigned) of
+ * a and b didn't matter (in fact they were equal). As soon as the value exceeds 127 the developer needs to decide
+ * whether c is signed or unsigned.
+ * If c is unsigned all future users of c must take care that they
+ * interpret it correctly. Also a comes from a signed context and could be negative.
+ * If a's MSB is set to indicate a negative value any computation that considers a unsigned must be wrong
+ * as it would interpret a as a big positive number instead of a negative number.
+ * If c is interpreted as signed, the computation is plain wrong (64 + 64 is not -128) because it leads to a number-overflow.
+ *
+ * {@code //Instead do this:}
+ * {@code byte a = 64;}
+ * {@code @Unsigned byte b = 64;}
+ * {@code short s = UnsignedNumbers.toUnsignedShort(b);}
+ * {@code short c = s + a;}
+ * {@code //--> c = 128;}
+ *
+ * @author JaniruTEC
+ * @see UnsignedNumbers
+ * @since 2.0
+ */
@Documented
@Retention(RetentionPolicy.RUNTIME)
//In Theory TYPE_USE should contain TYPE_PARAMETER,