jdk/src/java.prefs/windows/classes/java/util/prefs/WindowsPreferences.java
author mchung
Fri, 22 May 2015 16:43:39 -0700
changeset 30789 9eca83469588
parent 30641 701f6f90dc0b
child 32037 ab4526f4ac10
permissions -rw-r--r--
8074431: Remove native2ascii tool Reviewed-by: erikj, alanb, okutsu, mfang, naoto
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
30043
b0dd05ec3db1 8075156: (prefs) get*() and remove() should disallow the use of the null control character '\u0000' as key
bpb
parents: 25859
diff changeset
     2
 * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3861
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3861
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3861
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3861
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3861
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package java.util.prefs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.util.StringTokenizer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.io.ByteArrayOutputStream;
22951
5fd21112b2b6 8034043: Native methods for preferences API should not be in libjava
alanb
parents: 5506
diff changeset
    30
import java.security.AccessController;
5fd21112b2b6 8034043: Native methods for preferences API should not be in libjava
alanb
parents: 5506
diff changeset
    31
import java.security.PrivilegedAction;
5fd21112b2b6 8034043: Native methods for preferences API should not be in libjava
alanb
parents: 5506
diff changeset
    32
3861
a98a057ec335 6882376: Add internal support for JRE implementation to eliminate the dependency on logging
mchung
parents: 2
diff changeset
    33
import sun.util.logging.PlatformLogger;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 * Windows registry based implementation of  <tt>Preferences</tt>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * <tt>Preferences</tt>' <tt>systemRoot</tt> and <tt>userRoot</tt> are stored in
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 * <tt>HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Prefs</tt> and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * <tt>HKEY_CURRENT_USER\Software\JavaSoft\Prefs</tt> correspondingly.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * @author  Konstantin Kladko
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * @see Preferences
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * @see PreferencesFactory
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * @since 1.4
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
30043
b0dd05ec3db1 8075156: (prefs) get*() and remove() should disallow the use of the null control character '\u0000' as key
bpb
parents: 25859
diff changeset
    47
class WindowsPreferences extends AbstractPreferences {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
22951
5fd21112b2b6 8034043: Native methods for preferences API should not be in libjava
alanb
parents: 5506
diff changeset
    49
    static {
5fd21112b2b6 8034043: Native methods for preferences API should not be in libjava
alanb
parents: 5506
diff changeset
    50
        PrivilegedAction<Void> load = () -> {
5fd21112b2b6 8034043: Native methods for preferences API should not be in libjava
alanb
parents: 5506
diff changeset
    51
            System.loadLibrary("prefs");
5fd21112b2b6 8034043: Native methods for preferences API should not be in libjava
alanb
parents: 5506
diff changeset
    52
            return null;
5fd21112b2b6 8034043: Native methods for preferences API should not be in libjava
alanb
parents: 5506
diff changeset
    53
        };
5fd21112b2b6 8034043: Native methods for preferences API should not be in libjava
alanb
parents: 5506
diff changeset
    54
        AccessController.doPrivileged(load);
5fd21112b2b6 8034043: Native methods for preferences API should not be in libjava
alanb
parents: 5506
diff changeset
    55
    }
5fd21112b2b6 8034043: Native methods for preferences API should not be in libjava
alanb
parents: 5506
diff changeset
    56
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
     * Logger for error messages
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
     */
3861
a98a057ec335 6882376: Add internal support for JRE implementation to eliminate the dependency on logging
mchung
parents: 2
diff changeset
    60
    private static PlatformLogger logger;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
     * Windows registry path to <tt>Preferences</tt>'s root nodes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
     */
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
    65
    private static final byte[] WINDOWS_ROOT_PATH =
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
    66
        stringToByteArray("Software\\JavaSoft\\Prefs");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
     * Windows handles to <tt>HKEY_CURRENT_USER</tt> and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
     * <tt>HKEY_LOCAL_MACHINE</tt> hives.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    private static final int HKEY_CURRENT_USER = 0x80000001;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
    private static final int HKEY_LOCAL_MACHINE = 0x80000002;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
     * Mount point for <tt>Preferences</tt>'  user root.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    private static final int USER_ROOT_NATIVE_HANDLE = HKEY_CURRENT_USER;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
     * Mount point for <tt>Preferences</tt>'  system root.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    private static final int SYSTEM_ROOT_NATIVE_HANDLE = HKEY_LOCAL_MACHINE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
     * Maximum byte-encoded path length for Windows native functions,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
     * ending <tt>null</tt> character not included.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    private static final int MAX_WINDOWS_PATH_LENGTH = 256;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
     * User root node.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
    static final Preferences userRoot =
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
         new WindowsPreferences(USER_ROOT_NATIVE_HANDLE, WINDOWS_ROOT_PATH);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
     * System root node.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
    static final Preferences systemRoot =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
        new WindowsPreferences(SYSTEM_ROOT_NATIVE_HANDLE, WINDOWS_ROOT_PATH);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
    /*  Windows error codes. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
    private static final int ERROR_SUCCESS = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    private static final int ERROR_FILE_NOT_FOUND = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
    private static final int ERROR_ACCESS_DENIED = 5;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    /* Constants used to interpret returns of native functions    */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    private static final int NATIVE_HANDLE = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
    private static final int ERROR_CODE = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
    private static final int SUBKEYS_NUMBER = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    private static final int VALUES_NUMBER = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    private static final int MAX_KEY_LENGTH = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    private static final int MAX_VALUE_NAME_LENGTH = 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    private static final int DISPOSITION = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
    private static final int REG_CREATED_NEW_KEY = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    private static final int REG_OPENED_EXISTING_KEY = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
    private static final int NULL_NATIVE_HANDLE = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
    /* Windows security masks */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    private static final int DELETE = 0x10000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    private static final int KEY_QUERY_VALUE = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
    private static final int KEY_SET_VALUE = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    private static final int KEY_CREATE_SUB_KEY = 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
    private static final int KEY_ENUMERATE_SUB_KEYS = 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    private static final int KEY_READ = 0x20019;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    private static final int KEY_WRITE = 0x20006;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    private static final int KEY_ALL_ACCESS = 0xf003f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
     * Initial time between registry access attempts, in ms. The time is doubled
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
     * after each failing attempt (except the first).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
    private static int INIT_SLEEP_TIME = 50;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
     * Maximum number of registry access attempts.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    private static int MAX_ATTEMPTS = 5;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
     * BackingStore availability flag.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    private boolean isBackingStoreAvailable = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
     * Java wrapper for Windows registry API RegOpenKey()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
    private static native int[] WindowsRegOpenKey(int hKey, byte[] subKey,
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   150
                                                  int securityMask);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
     * Retries RegOpenKey() MAX_ATTEMPTS times before giving up.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    private static int[] WindowsRegOpenKey1(int hKey, byte[] subKey,
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   155
                                            int securityMask) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
        int[] result = WindowsRegOpenKey(hKey, subKey, securityMask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
        if (result[ERROR_CODE] == ERROR_SUCCESS) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
            return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
        } else if (result[ERROR_CODE] == ERROR_FILE_NOT_FOUND) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
            logger().warning("Trying to recreate Windows registry node " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
            byteArrayToString(subKey) + " at root 0x" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
            Integer.toHexString(hKey) + ".");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
            // Try recreation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
            int handle = WindowsRegCreateKeyEx(hKey, subKey)[NATIVE_HANDLE];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
            WindowsRegCloseKey(handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
            return WindowsRegOpenKey(hKey, subKey, securityMask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
        } else if (result[ERROR_CODE] != ERROR_ACCESS_DENIED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
            long sleepTime = INIT_SLEEP_TIME;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
            for (int i = 0; i < MAX_ATTEMPTS; i++) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   170
                try {
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   171
                    Thread.sleep(sleepTime);
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   172
                } catch(InterruptedException e) {
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   173
                    return result;
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   174
                }
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   175
                sleepTime *= 2;
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   176
                result = WindowsRegOpenKey(hKey, subKey, securityMask);
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   177
                if (result[ERROR_CODE] == ERROR_SUCCESS) {
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   178
                    return result;
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   179
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
     /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
     * Java wrapper for Windows registry API RegCloseKey()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
    private static native int WindowsRegCloseKey(int hKey);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
     * Java wrapper for Windows registry API RegCreateKeyEx()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
    private static native int[] WindowsRegCreateKeyEx(int hKey, byte[] subKey);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
     * Retries RegCreateKeyEx() MAX_ATTEMPTS times before giving up.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
    private static int[] WindowsRegCreateKeyEx1(int hKey, byte[] subKey) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
        int[] result = WindowsRegCreateKeyEx(hKey, subKey);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
        if (result[ERROR_CODE] == ERROR_SUCCESS) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   201
            return result;
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   202
        } else {
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   203
            long sleepTime = INIT_SLEEP_TIME;
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   204
            for (int i = 0; i < MAX_ATTEMPTS; i++) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
                    Thread.sleep(sleepTime);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
                } catch(InterruptedException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
                    return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
                sleepTime *= 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
                result = WindowsRegCreateKeyEx(hKey, subKey);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
                if (result[ERROR_CODE] == ERROR_SUCCESS) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   213
                    return result;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
     * Java wrapper for Windows registry API RegDeleteKey()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
    private static native int WindowsRegDeleteKey(int hKey, byte[] subKey);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
     * Java wrapper for Windows registry API RegFlushKey()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
    private static native int WindowsRegFlushKey(int hKey);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
     * Retries RegFlushKey() MAX_ATTEMPTS times before giving up.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
    private static int WindowsRegFlushKey1(int hKey) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
        int result = WindowsRegFlushKey(hKey);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        if (result == ERROR_SUCCESS) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   235
            return result;
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   236
        } else {
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   237
            long sleepTime = INIT_SLEEP_TIME;
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   238
            for (int i = 0; i < MAX_ATTEMPTS; i++) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
                    Thread.sleep(sleepTime);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
                } catch(InterruptedException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
                    return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
                sleepTime *= 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
                result = WindowsRegFlushKey(hKey);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
                if (result == ERROR_SUCCESS) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   247
                    return result;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
     * Java wrapper for Windows registry API RegQueryValueEx()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
    private static native byte[] WindowsRegQueryValueEx(int hKey,
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   258
                                                        byte[] valueName);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
     * Java wrapper for Windows registry API RegSetValueEx()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
    private static native int WindowsRegSetValueEx(int hKey, byte[] valueName,
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   263
                                                   byte[] value);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
     * Retries RegSetValueEx() MAX_ATTEMPTS times before giving up.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    private static int WindowsRegSetValueEx1(int hKey, byte[] valueName,
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   268
                                             byte[] value) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
        int result = WindowsRegSetValueEx(hKey, valueName, value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
        if (result == ERROR_SUCCESS) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   271
            return result;
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   272
        } else {
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   273
            long sleepTime = INIT_SLEEP_TIME;
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   274
            for (int i = 0; i < MAX_ATTEMPTS; i++) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
                    Thread.sleep(sleepTime);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
                } catch(InterruptedException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
                    return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
                sleepTime *= 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
                result = WindowsRegSetValueEx(hKey, valueName, value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
                if (result == ERROR_SUCCESS) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   283
                    return result;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
     * Java wrapper for Windows registry API RegDeleteValue()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
    private static native int WindowsRegDeleteValue(int hKey, byte[] valueName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
     * Java wrapper for Windows registry API RegQueryInfoKey()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
    private static native int[] WindowsRegQueryInfoKey(int hKey);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
     * Retries RegQueryInfoKey() MAX_ATTEMPTS times before giving up.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
    private static int[] WindowsRegQueryInfoKey1(int hKey) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
        int[] result = WindowsRegQueryInfoKey(hKey);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
        if (result[ERROR_CODE] == ERROR_SUCCESS) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   306
            return result;
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   307
        } else {
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   308
            long sleepTime = INIT_SLEEP_TIME;
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   309
            for (int i = 0; i < MAX_ATTEMPTS; i++) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
                    Thread.sleep(sleepTime);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
                } catch(InterruptedException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
                    return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
                sleepTime *= 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
                result = WindowsRegQueryInfoKey(hKey);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
                if (result[ERROR_CODE] == ERROR_SUCCESS) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   318
                    return result;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
     * Java wrapper for Windows registry API RegEnumKeyEx()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
    private static native byte[] WindowsRegEnumKeyEx(int hKey, int subKeyIndex,
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   329
                                                     int maxKeyLength);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
     * Retries RegEnumKeyEx() MAX_ATTEMPTS times before giving up.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
    private static byte[] WindowsRegEnumKeyEx1(int hKey, int subKeyIndex,
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   335
                                               int maxKeyLength) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
        byte[] result = WindowsRegEnumKeyEx(hKey, subKeyIndex, maxKeyLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
        if (result != null) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   338
            return result;
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   339
        } else {
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   340
            long sleepTime = INIT_SLEEP_TIME;
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   341
            for (int i = 0; i < MAX_ATTEMPTS; i++) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
                    Thread.sleep(sleepTime);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
                } catch(InterruptedException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
                    return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
                sleepTime *= 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
                result = WindowsRegEnumKeyEx(hKey, subKeyIndex, maxKeyLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
                if (result != null) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   350
                    return result;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
     * Java wrapper for Windows registry API RegEnumValue()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
    private static native byte[] WindowsRegEnumValue(int hKey, int valueIndex,
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   361
                                                     int maxValueNameLength);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
     * Retries RegEnumValueEx() MAX_ATTEMPTS times before giving up.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
    private static byte[] WindowsRegEnumValue1(int hKey, int valueIndex,
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   366
                                               int maxValueNameLength) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
        byte[] result = WindowsRegEnumValue(hKey, valueIndex,
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   368
                                            maxValueNameLength);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
        if (result != null) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   370
            return result;
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   371
        } else {
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   372
            long sleepTime = INIT_SLEEP_TIME;
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   373
            for (int i = 0; i < MAX_ATTEMPTS; i++) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
                    Thread.sleep(sleepTime);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
                } catch(InterruptedException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
                    return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
                sleepTime *= 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
                result = WindowsRegEnumValue(hKey, valueIndex,
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   381
                                             maxValueNameLength);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
                if (result != null) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   383
                    return result;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
     * Constructs a <tt>WindowsPreferences</tt> node, creating underlying
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
     * Windows registry node and all its Windows parents, if they are not yet
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
     * created.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
     * Logs a warning message, if Windows Registry is unavailable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
    private WindowsPreferences(WindowsPreferences parent, String name) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
        super(parent, name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
        int parentNativeHandle = parent.openKey(KEY_CREATE_SUB_KEY, KEY_READ);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
        if (parentNativeHandle == NULL_NATIVE_HANDLE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
            // if here, openKey failed and logged
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
            isBackingStoreAvailable = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
        int[] result =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
               WindowsRegCreateKeyEx1(parentNativeHandle, toWindowsName(name));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
        if (result[ERROR_CODE] != ERROR_SUCCESS) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   407
            logger().warning("Could not create windows registry node " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   408
                    byteArrayToString(windowsAbsolutePath()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   409
                    " at root 0x" + Integer.toHexString(rootNativeHandle()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   410
                    ". Windows RegCreateKeyEx(...) returned error code " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   411
                    result[ERROR_CODE] + ".");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
            isBackingStoreAvailable = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
        newNode = (result[DISPOSITION] == REG_CREATED_NEW_KEY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
        closeKey(parentNativeHandle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
        closeKey(result[NATIVE_HANDLE]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
     * Constructs a root node creating the underlying
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
     * Windows registry node and all of its parents, if they have not yet been
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
     * created.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
     * Logs a warning message, if Windows Registry is unavailable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
     * @param rootNativeHandle Native handle to one of Windows top level keys.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
     * @param rootDirectory Path to root directory, as a byte-encoded string.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
    private  WindowsPreferences(int rootNativeHandle, byte[] rootDirectory) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   429
        super(null, "");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
        int[] result =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
                WindowsRegCreateKeyEx1(rootNativeHandle, rootDirectory);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
        if (result[ERROR_CODE] != ERROR_SUCCESS) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
            logger().warning("Could not open/create prefs root node " +
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   434
                    byteArrayToString(windowsAbsolutePath()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   435
                    " at root 0x" + Integer.toHexString(rootNativeHandle()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   436
                    ". Windows RegCreateKeyEx(...) returned error code " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   437
                    result[ERROR_CODE] + ".");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
            isBackingStoreAvailable = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
        // Check if a new node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
        newNode = (result[DISPOSITION] == REG_CREATED_NEW_KEY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
        closeKey(result[NATIVE_HANDLE]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
     * Returns Windows absolute path of the current node as a byte array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
     * Java "/" separator is transformed into Windows "\".
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
     * @see Preferences#absolutePath()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
    private byte[] windowsAbsolutePath() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
        ByteArrayOutputStream bstream = new ByteArrayOutputStream();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
        bstream.write(WINDOWS_ROOT_PATH, 0, WINDOWS_ROOT_PATH.length-1);
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   454
        StringTokenizer tokenizer = new StringTokenizer(absolutePath(), "/");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
        while (tokenizer.hasMoreTokens()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
            bstream.write((byte)'\\');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
            String nextName = tokenizer.nextToken();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
            byte[] windowsNextName = toWindowsName(nextName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
            bstream.write(windowsNextName, 0, windowsNextName.length-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
        bstream.write(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
        return bstream.toByteArray();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
     * Opens current node's underlying Windows registry key using a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
     * given security mask.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
     * @param securityMask Windows security mask.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
     * @return Windows registry key's handle.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
     * @see #openKey(byte[], int)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
     * @see #openKey(int, byte[], int)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
     * @see #closeKey(int)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
    private int openKey(int securityMask) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
        return openKey(securityMask, securityMask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
     * Opens current node's underlying Windows registry key using a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
     * given security mask.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
     * @param mask1 Preferred Windows security mask.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
     * @param mask2 Alternate Windows security mask.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
     * @return Windows registry key's handle.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
     * @see #openKey(byte[], int)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
     * @see #openKey(int, byte[], int)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
     * @see #closeKey(int)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
    private int openKey(int mask1, int mask2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
        return openKey(windowsAbsolutePath(), mask1,  mask2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
     /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
     * Opens Windows registry key at a given absolute path using a given
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
     * security mask.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
     * @param windowsAbsolutePath Windows absolute path of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
     *        key as a byte-encoded string.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
     * @param mask1 Preferred Windows security mask.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
     * @param mask2 Alternate Windows security mask.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
     * @return Windows registry key's handle.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
     * @see #openKey(int)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
     * @see #openKey(int, byte[],int)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
     * @see #closeKey(int)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
    private int openKey(byte[] windowsAbsolutePath, int mask1, int mask2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
        /*  Check if key's path is short enough be opened at once
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
            otherwise use a path-splitting procedure */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
        if (windowsAbsolutePath.length <= MAX_WINDOWS_PATH_LENGTH + 1) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   508
            int[] result = WindowsRegOpenKey1(rootNativeHandle(),
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   509
                                              windowsAbsolutePath, mask1);
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   510
            if (result[ERROR_CODE] == ERROR_ACCESS_DENIED && mask2 != mask1)
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   511
                result = WindowsRegOpenKey1(rootNativeHandle(),
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   512
                                            windowsAbsolutePath, mask2);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   514
            if (result[ERROR_CODE] != ERROR_SUCCESS) {
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   515
                logger().warning("Could not open windows registry node " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   516
                        byteArrayToString(windowsAbsolutePath()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   517
                        " at root 0x" +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   518
                        Integer.toHexString(rootNativeHandle()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   519
                        ". Windows RegOpenKey(...) returned error code " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   520
                        result[ERROR_CODE] + ".");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
                result[NATIVE_HANDLE] = NULL_NATIVE_HANDLE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
                if (result[ERROR_CODE] == ERROR_ACCESS_DENIED) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   523
                    throw new SecurityException(
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   524
                            "Could not open windows registry node " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   525
                            byteArrayToString(windowsAbsolutePath()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   526
                            " at root 0x" +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   527
                            Integer.toHexString(rootNativeHandle()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   528
                            ": Access denied");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
                }
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   530
            }
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   531
            return result[NATIVE_HANDLE];
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
            return openKey(rootNativeHandle(), windowsAbsolutePath, mask1, mask2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
     /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
     * Opens Windows registry key at a given relative path
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
     * with respect to a given Windows registry key.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
     * @param windowsAbsolutePath Windows relative path of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
     *        key as a byte-encoded string.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
     * @param nativeHandle handle to the base Windows key.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
     * @param mask1 Preferred Windows security mask.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
     * @param mask2 Alternate Windows security mask.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
     * @return Windows registry key's handle.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
     * @see #openKey(int)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
     * @see #openKey(byte[],int)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
     * @see #closeKey(int)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
    private int openKey(int nativeHandle, byte[] windowsRelativePath,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
                        int mask1, int mask2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
    /* If the path is short enough open at once. Otherwise split the path */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
        if (windowsRelativePath.length <= MAX_WINDOWS_PATH_LENGTH + 1 ) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   554
            int[] result = WindowsRegOpenKey1(nativeHandle,
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   555
                                              windowsRelativePath, mask1);
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   556
            if (result[ERROR_CODE] == ERROR_ACCESS_DENIED && mask2 != mask1)
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   557
                result = WindowsRegOpenKey1(nativeHandle,
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   558
                                            windowsRelativePath, mask2);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   560
            if (result[ERROR_CODE] != ERROR_SUCCESS) {
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   561
                logger().warning("Could not open windows registry node " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   562
                        byteArrayToString(windowsAbsolutePath()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   563
                        " at root 0x" + Integer.toHexString(nativeHandle) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   564
                        ". Windows RegOpenKey(...) returned error code " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   565
                        result[ERROR_CODE] + ".");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
                result[NATIVE_HANDLE] = NULL_NATIVE_HANDLE;
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   567
            }
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   568
            return result[NATIVE_HANDLE];
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
            int separatorPosition = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
            // Be greedy - open the longest possible path
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
            for (int i = MAX_WINDOWS_PATH_LENGTH; i > 0; i--) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
                if (windowsRelativePath[i] == ((byte)'\\')) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
                    separatorPosition = i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
            // Split the path and do the recursion
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
            byte[] nextRelativeRoot = new byte[separatorPosition+1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
            System.arraycopy(windowsRelativePath, 0, nextRelativeRoot,0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
                                                      separatorPosition);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
            nextRelativeRoot[separatorPosition] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
            byte[] nextRelativePath = new byte[windowsRelativePath.length -
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
                                      separatorPosition - 1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
            System.arraycopy(windowsRelativePath, separatorPosition+1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
                             nextRelativePath, 0, nextRelativePath.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
            int nextNativeHandle = openKey(nativeHandle, nextRelativeRoot,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
                                           mask1, mask2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
            if (nextNativeHandle == NULL_NATIVE_HANDLE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
                return NULL_NATIVE_HANDLE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
            int result = openKey(nextNativeHandle, nextRelativePath,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
                                 mask1,mask2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
            closeKey(nextNativeHandle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
            return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
     /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
     * Closes Windows registry key.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
     * Logs a warning if Windows registry is unavailable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
     * @param key's Windows registry handle.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
     * @see #openKey(int)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
     * @see #openKey(byte[],int)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
     * @see #openKey(int, byte[],int)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
    */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
    private void closeKey(int nativeHandle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
        int result = WindowsRegCloseKey(nativeHandle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
        if (result != ERROR_SUCCESS) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   610
            logger().warning("Could not close windows registry node " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   611
                    byteArrayToString(windowsAbsolutePath()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   612
                    " at root 0x" +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   613
                    Integer.toHexString(rootNativeHandle()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   614
                    ". Windows RegCloseKey(...) returned error code " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   615
                    result + ".");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
     /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
     * Implements <tt>AbstractPreferences</tt> <tt>putSpi()</tt> method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
     * Puts name-value pair into the underlying Windows registry node.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
     * Logs a warning, if Windows registry is unavailable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
     * @see #getSpi(String)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
    protected void putSpi(String javaName, String value) {
30043
b0dd05ec3db1 8075156: (prefs) get*() and remove() should disallow the use of the null control character '\u0000' as key
bpb
parents: 25859
diff changeset
   626
        int nativeHandle = openKey(KEY_SET_VALUE);
b0dd05ec3db1 8075156: (prefs) get*() and remove() should disallow the use of the null control character '\u0000' as key
bpb
parents: 25859
diff changeset
   627
        if (nativeHandle == NULL_NATIVE_HANDLE) {
b0dd05ec3db1 8075156: (prefs) get*() and remove() should disallow the use of the null control character '\u0000' as key
bpb
parents: 25859
diff changeset
   628
            isBackingStoreAvailable = false;
b0dd05ec3db1 8075156: (prefs) get*() and remove() should disallow the use of the null control character '\u0000' as key
bpb
parents: 25859
diff changeset
   629
            return;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
        }
30043
b0dd05ec3db1 8075156: (prefs) get*() and remove() should disallow the use of the null control character '\u0000' as key
bpb
parents: 25859
diff changeset
   631
        int result = WindowsRegSetValueEx1(nativeHandle,
b0dd05ec3db1 8075156: (prefs) get*() and remove() should disallow the use of the null control character '\u0000' as key
bpb
parents: 25859
diff changeset
   632
                toWindowsName(javaName), toWindowsValueString(value));
b0dd05ec3db1 8075156: (prefs) get*() and remove() should disallow the use of the null control character '\u0000' as key
bpb
parents: 25859
diff changeset
   633
        if (result != ERROR_SUCCESS) {
b0dd05ec3db1 8075156: (prefs) get*() and remove() should disallow the use of the null control character '\u0000' as key
bpb
parents: 25859
diff changeset
   634
            logger().warning("Could not assign value to key " +
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   635
                    byteArrayToString(toWindowsName(javaName)) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   636
                    " at Windows registry node " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   637
                    byteArrayToString(windowsAbsolutePath()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   638
                    " at root 0x" +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   639
                    Integer.toHexString(rootNativeHandle()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   640
                    ". Windows RegSetValueEx(...) returned error code " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   641
                    result + ".");
30043
b0dd05ec3db1 8075156: (prefs) get*() and remove() should disallow the use of the null control character '\u0000' as key
bpb
parents: 25859
diff changeset
   642
            isBackingStoreAvailable = false;
b0dd05ec3db1 8075156: (prefs) get*() and remove() should disallow the use of the null control character '\u0000' as key
bpb
parents: 25859
diff changeset
   643
        }
b0dd05ec3db1 8075156: (prefs) get*() and remove() should disallow the use of the null control character '\u0000' as key
bpb
parents: 25859
diff changeset
   644
        closeKey(nativeHandle);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
     * Implements <tt>AbstractPreferences</tt> <tt>getSpi()</tt> method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
     * Gets a string value from the underlying Windows registry node.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
     * Logs a warning, if Windows registry is unavailable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
     * @see #putSpi(String, String)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
    protected String getSpi(String javaName) {
30043
b0dd05ec3db1 8075156: (prefs) get*() and remove() should disallow the use of the null control character '\u0000' as key
bpb
parents: 25859
diff changeset
   654
        int nativeHandle = openKey(KEY_QUERY_VALUE);
b0dd05ec3db1 8075156: (prefs) get*() and remove() should disallow the use of the null control character '\u0000' as key
bpb
parents: 25859
diff changeset
   655
        if (nativeHandle == NULL_NATIVE_HANDLE) {
b0dd05ec3db1 8075156: (prefs) get*() and remove() should disallow the use of the null control character '\u0000' as key
bpb
parents: 25859
diff changeset
   656
            return null;
b0dd05ec3db1 8075156: (prefs) get*() and remove() should disallow the use of the null control character '\u0000' as key
bpb
parents: 25859
diff changeset
   657
        }
b0dd05ec3db1 8075156: (prefs) get*() and remove() should disallow the use of the null control character '\u0000' as key
bpb
parents: 25859
diff changeset
   658
        Object resultObject = WindowsRegQueryValueEx(nativeHandle,
b0dd05ec3db1 8075156: (prefs) get*() and remove() should disallow the use of the null control character '\u0000' as key
bpb
parents: 25859
diff changeset
   659
                toWindowsName(javaName));
b0dd05ec3db1 8075156: (prefs) get*() and remove() should disallow the use of the null control character '\u0000' as key
bpb
parents: 25859
diff changeset
   660
        if (resultObject == null) {
b0dd05ec3db1 8075156: (prefs) get*() and remove() should disallow the use of the null control character '\u0000' as key
bpb
parents: 25859
diff changeset
   661
            closeKey(nativeHandle);
b0dd05ec3db1 8075156: (prefs) get*() and remove() should disallow the use of the null control character '\u0000' as key
bpb
parents: 25859
diff changeset
   662
            return null;
b0dd05ec3db1 8075156: (prefs) get*() and remove() should disallow the use of the null control character '\u0000' as key
bpb
parents: 25859
diff changeset
   663
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
        closeKey(nativeHandle);
30043
b0dd05ec3db1 8075156: (prefs) get*() and remove() should disallow the use of the null control character '\u0000' as key
bpb
parents: 25859
diff changeset
   665
        return toJavaValueString((byte[]) resultObject);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
     * Implements <tt>AbstractPreferences</tt> <tt>removeSpi()</tt> method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
     * Deletes a string name-value pair from the underlying Windows registry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
     * node, if this value still exists.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
     * Logs a warning, if Windows registry is unavailable or key has already
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
     * been deleted.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
    protected void removeSpi(String key) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
        int nativeHandle = openKey(KEY_SET_VALUE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
        if (nativeHandle == NULL_NATIVE_HANDLE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
        int result =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
            WindowsRegDeleteValue(nativeHandle, toWindowsName(key));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
        if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   683
            logger().warning("Could not delete windows registry value " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   684
                    byteArrayToString(windowsAbsolutePath()) + "\\" +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   685
                    toWindowsName(key) + " at root 0x" +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   686
                    Integer.toHexString(rootNativeHandle()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   687
                    ". Windows RegDeleteValue(...) returned error code " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   688
                    result + ".");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
            isBackingStoreAvailable = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
        closeKey(nativeHandle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
     * Implements <tt>AbstractPreferences</tt> <tt>keysSpi()</tt> method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
     * Gets value names from the underlying Windows registry node.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
     * Throws a BackingStoreException and logs a warning, if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
     * Windows registry is unavailable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
    protected String[] keysSpi() throws BackingStoreException{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
        // Find out the number of values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
        int nativeHandle = openKey(KEY_QUERY_VALUE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
        if (nativeHandle == NULL_NATIVE_HANDLE) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   704
            throw new BackingStoreException(
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   705
                    "Could not open windows registry node " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   706
                    byteArrayToString(windowsAbsolutePath()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   707
                    " at root 0x" +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   708
                    Integer.toHexString(rootNativeHandle()) + ".");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
        int[] result =  WindowsRegQueryInfoKey1(nativeHandle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
        if (result[ERROR_CODE] != ERROR_SUCCESS) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   712
            String info = "Could not query windows registry node " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   713
                    byteArrayToString(windowsAbsolutePath()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   714
                    " at root 0x" +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   715
                    Integer.toHexString(rootNativeHandle()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   716
                    ". Windows RegQueryInfoKeyEx(...) returned error code " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   717
                    result[ERROR_CODE] + ".";
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
            logger().warning(info);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
            throw new BackingStoreException(info);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
        int maxValueNameLength = result[MAX_VALUE_NAME_LENGTH];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
        int valuesNumber = result[VALUES_NUMBER];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
        if (valuesNumber == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
            closeKey(nativeHandle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
            return new String[0];
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   726
        }
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   727
        // Get the values
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   728
        String[] valueNames = new String[valuesNumber];
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   729
        for (int i = 0; i < valuesNumber; i++) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
            byte[] windowsName = WindowsRegEnumValue1(nativeHandle, i,
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   731
                                                      maxValueNameLength+1);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
            if (windowsName == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
                String info =
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   734
                    "Could not enumerate value #" + i + "  of windows node " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   735
                    byteArrayToString(windowsAbsolutePath()) + " at root 0x" +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   736
                    Integer.toHexString(rootNativeHandle()) + ".";
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
                logger().warning(info);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
                throw new BackingStoreException(info);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
            valueNames[i] = toJavaName(windowsName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
        closeKey(nativeHandle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
        return valueNames;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
     * Implements <tt>AbstractPreferences</tt> <tt>childrenNamesSpi()</tt> method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
     * Calls Windows registry to retrive children of this node.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
     * Throws a BackingStoreException and logs a warning message,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
     * if Windows registry is not available.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
    protected String[] childrenNamesSpi() throws BackingStoreException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
        // Open key
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   754
        int nativeHandle = openKey(KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
        if (nativeHandle == NULL_NATIVE_HANDLE) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   756
            throw new BackingStoreException(
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   757
                    "Could not open windows registry node " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   758
                    byteArrayToString(windowsAbsolutePath()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   759
                    " at root 0x" +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   760
                    Integer.toHexString(rootNativeHandle()) + ".");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
        // Get number of children
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
        int[] result =  WindowsRegQueryInfoKey1(nativeHandle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
        if (result[ERROR_CODE] != ERROR_SUCCESS) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   765
            String info = "Could not query windows registry node " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   766
                    byteArrayToString(windowsAbsolutePath()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   767
                    " at root 0x" + Integer.toHexString(rootNativeHandle()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   768
                    ". Windows RegQueryInfoKeyEx(...) returned error code " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   769
                    result[ERROR_CODE] + ".";
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
            logger().warning(info);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
            throw new BackingStoreException(info);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
        int maxKeyLength = result[MAX_KEY_LENGTH];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
        int subKeysNumber = result[SUBKEYS_NUMBER];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
        if (subKeysNumber == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
            closeKey(nativeHandle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
            return new String[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
        String[] subkeys = new String[subKeysNumber];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
        String[] children = new String[subKeysNumber];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
        // Get children
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
        for (int i = 0; i < subKeysNumber; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
            byte[] windowsName = WindowsRegEnumKeyEx1(nativeHandle, i,
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   784
                                                      maxKeyLength+1);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
            if (windowsName == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
                String info =
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   787
                    "Could not enumerate key #" + i + "  of windows node " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   788
                    byteArrayToString(windowsAbsolutePath()) + " at root 0x" +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   789
                    Integer.toHexString(rootNativeHandle()) + ". ";
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
                logger().warning(info);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
                throw new BackingStoreException(info);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
            String javaName = toJavaName(windowsName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
            children[i] = javaName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
        closeKey(nativeHandle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
        return children;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
     * Implements <tt>Preferences</tt> <tt>flush()</tt> method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
     * Flushes Windows registry changes to disk.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
     * Throws a BackingStoreException and logs a warning message if Windows
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
     * registry is not available.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
    public void flush() throws BackingStoreException{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
        if (isRemoved()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
            parent.flush();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
        if (!isBackingStoreAvailable) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
            throw new BackingStoreException(
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   814
                    "flush(): Backing store not available.");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
        int nativeHandle = openKey(KEY_READ);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
        if (nativeHandle == NULL_NATIVE_HANDLE) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   818
            throw new BackingStoreException(
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   819
                    "Could not open windows registry node " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   820
                    byteArrayToString(windowsAbsolutePath()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   821
                    " at root 0x" +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   822
                    Integer.toHexString(rootNativeHandle()) + ".");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
        int result = WindowsRegFlushKey1(nativeHandle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
        if (result != ERROR_SUCCESS) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   826
            String info = "Could not flush windows registry node " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   827
                    byteArrayToString(windowsAbsolutePath()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   828
                    " at root 0x" +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   829
                    Integer.toHexString(rootNativeHandle()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   830
                    ". Windows RegFlushKey(...) returned error code " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   831
                    result + ".";
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
            logger().warning(info);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
            throw new BackingStoreException(info);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
        closeKey(nativeHandle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
     * Implements <tt>Preferences</tt> <tt>sync()</tt> method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
     * Flushes Windows registry changes to disk. Equivalent to flush().
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
     * @see flush()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
    public void sync() throws BackingStoreException{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
        if (isRemoved())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
            throw new IllegalStateException("Node has been removed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
        flush();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
     * Implements <tt>AbstractPreferences</tt> <tt>childSpi()</tt> method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
     * Constructs a child node with a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
     * given name and creates its underlying Windows registry node,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
     * if it does not exist.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
     * Logs a warning message, if Windows Registry is unavailable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
    protected AbstractPreferences childSpi(String name) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   858
        return new WindowsPreferences(this, name);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
     * Implements <tt>AbstractPreferences</tt> <tt>removeNodeSpi()</tt> method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
     * Deletes underlying Windows registry node.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
     * Throws a BackingStoreException and logs a warning, if Windows registry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
     * is not available.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
    public void removeNodeSpi() throws BackingStoreException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
        int parentNativeHandle =
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   869
                ((WindowsPreferences)parent()).openKey(DELETE);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
        if (parentNativeHandle == NULL_NATIVE_HANDLE) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   871
            throw new BackingStoreException(
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   872
                    "Could not open parent windows registry node of " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   873
                    byteArrayToString(windowsAbsolutePath()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   874
                    " at root 0x" +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   875
                    Integer.toHexString(rootNativeHandle()) + ".");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
        int result =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
                WindowsRegDeleteKey(parentNativeHandle, toWindowsName(name()));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
        if (result != ERROR_SUCCESS) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   880
            String info = "Could not delete windows registry node " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   881
                    byteArrayToString(windowsAbsolutePath()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   882
                    " at root 0x" + Integer.toHexString(rootNativeHandle()) +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   883
                    ". Windows RegDeleteKeyEx(...) returned error code " +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   884
                    result + ".";
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
            logger().warning(info);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
            throw new BackingStoreException(info);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
        closeKey(parentNativeHandle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
     * Converts value's or node's name from its byte array representation to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
     * java string. Two encodings, simple and altBase64 are used. See
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
     * {@link #toWindowsName(String) toWindowsName()} for a detailed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
     * description of encoding conventions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
     * @param windowsNameArray Null-terminated byte array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
    private static String toJavaName(byte[] windowsNameArray) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
        String windowsName = byteArrayToString(windowsNameArray);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
        // check if Alt64
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   901
        if ((windowsName.length() > 1) &&
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   902
                (windowsName.substring(0, 2).equals("/!"))) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
            return toJavaAlt64Name(windowsName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
        }
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   905
        StringBuilder javaName = new StringBuilder();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
        char ch;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
        // Decode from simple encoding
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   908
        for (int i = 0; i < windowsName.length(); i++) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
            if ((ch = windowsName.charAt(i)) == '/') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
                char next = ' ';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
                if ((windowsName.length() > i + 1) &&
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   912
                        ((next = windowsName.charAt(i+1)) >= 'A') &&
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   913
                        (next <= 'Z')) {
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   914
                    ch = next;
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   915
                    i++;
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   916
                } else if ((windowsName.length() > i + 1) &&
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   917
                           (next == '/')) {
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   918
                    ch = '\\';
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   919
                    i++;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
            } else if (ch == '\\') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
                ch = '/';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
            javaName.append(ch);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
        return javaName.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
     * Converts value's or node's name from its Windows representation to java
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
     * string, using altBase64 encoding. See
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
     * {@link #toWindowsName(String) toWindowsName()} for a detailed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
     * description of encoding conventions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
    private static String toJavaAlt64Name(String windowsName) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
        byte[] byteBuffer =
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   938
                Base64.altBase64ToByteArray(windowsName.substring(2));
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   939
        StringBuilder result = new StringBuilder();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
        for (int i = 0; i < byteBuffer.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
            int firstbyte = (byteBuffer[i++] & 0xff);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
            int secondbyte =  (byteBuffer[i] & 0xff);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
            result.append((char)((firstbyte << 8) + secondbyte));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
        return result.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
     * Converts value's or node's name to its Windows representation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
     * as a byte-encoded string.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
     * Two encodings, simple and altBase64 are used.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
     * <i>Simple</i> encoding is used, if java string does not contain
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
     * any characters less, than 0x0020, or greater, than 0x007f.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
     * Simple encoding adds "/" character to capital letters, i.e.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
     * "A" is encoded as "/A". Character '\' is encoded as '//',
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
     * '/' is encoded as '\'.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
     * The constructed string is converted to byte array by truncating the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
     * highest byte and adding the terminating <tt>null</tt> character.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
     * <i>altBase64</i>  encoding is used, if java string does contain at least
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
     * one character less, than 0x0020, or greater, than 0x007f.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
     * This encoding is marked by setting first two bytes of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
     * Windows string to '/!'. The java name is then encoded using
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
     * byteArrayToAltBase64() method from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
     * Base64 class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
    private static byte[] toWindowsName(String javaName) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   969
        StringBuilder windowsName = new StringBuilder();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
        for (int i = 0; i < javaName.length(); i++) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   971
            char ch = javaName.charAt(i);
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   972
            if ((ch < 0x0020) || (ch > 0x007f)) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
                // If a non-trivial character encountered, use altBase64
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
                return toWindowsAlt64Name(javaName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
            if (ch == '\\') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
                windowsName.append("//");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
            } else if (ch == '/') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
                windowsName.append('\\');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
            } else if ((ch >= 'A') && (ch <='Z')) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
   981
                windowsName.append('/').append(ch);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
                windowsName.append(ch);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
        return stringToByteArray(windowsName.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
     * Converts value's or node's name to its Windows representation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
     * as a byte-encoded string, using altBase64 encoding. See
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
     * {@link #toWindowsName(String) toWindowsName()} for a detailed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
     * description of encoding conventions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
    private static byte[] toWindowsAlt64Name(String javaName) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
        byte[] javaNameArray = new byte[2*javaName.length()];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
        // Convert to byte pairs
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
        int counter = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
        for (int i = 0; i < javaName.length();i++) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1000
            int ch = javaName.charAt(i);
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1001
            javaNameArray[counter++] = (byte)(ch >>> 8);
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1002
            javaNameArray[counter++] = (byte)ch;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1005
        return stringToByteArray("/!" +
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1006
                Base64.byteArrayToAltBase64(javaNameArray));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
     * Converts value string from its Windows representation
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
     * to java string.  See
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
     * {@link #toWindowsValueString(String) toWindowsValueString()} for the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
     * description of the encoding algorithm.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
     private static String toJavaValueString(byte[] windowsNameArray) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
        String windowsName = byteArrayToString(windowsNameArray);
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1017
        StringBuilder javaName = new StringBuilder();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
        char ch;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
        for (int i = 0; i < windowsName.length(); i++){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
            if ((ch = windowsName.charAt(i)) == '/') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
                char next = ' ';
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
                if (windowsName.length() > i + 1 &&
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1024
                        (next = windowsName.charAt(i + 1)) == 'u') {
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1025
                    if (windowsName.length() < i + 6) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
                    } else {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1028
                        ch = (char)Integer.parseInt(
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1029
                                windowsName.substring(i + 2, i + 6), 16);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
                        i += 5;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
                } else
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
                if ((windowsName.length() > i + 1) &&
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1034
                        ((windowsName.charAt(i+1)) >= 'A') &&
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1035
                        (next <= 'Z')) {
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1036
                    ch = next;
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1037
                    i++;
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1038
                } else if ((windowsName.length() > i + 1) &&
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1039
                        (next == '/')) {
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1040
                    ch = '\\';
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1041
                    i++;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
            } else if (ch == '\\') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
                ch = '/';
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
            javaName.append(ch);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
        return javaName.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
     * Converts value string to it Windows representation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
     * as a byte-encoded string.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
     * Encoding algorithm adds "/" character to capital letters, i.e.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
     * "A" is encoded as "/A". Character '\' is encoded as '//',
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
     * '/' is encoded as  '\'.
30789
9eca83469588 8074431: Remove native2ascii tool
mchung
parents: 30641
diff changeset
  1057
     * Then convert java string to a byte array of ASCII characters.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
    private static byte[] toWindowsValueString(String javaName) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1060
        StringBuilder windowsName = new StringBuilder();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
        for (int i = 0; i < javaName.length(); i++) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1062
            char ch = javaName.charAt(i);
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1063
            if ((ch < 0x0020) || (ch > 0x007f)){
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
                // write \udddd
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
                windowsName.append("/u");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
                String hex = Integer.toHexString(javaName.charAt(i));
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1067
                StringBuilder hex4 = new StringBuilder(hex);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
                hex4.reverse();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
                int len = 4 - hex4.length();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
                for (int j = 0; j < len; j++){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
                    hex4.append('0');
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
                for (int j = 0; j < 4; j++){
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
                    windowsName.append(hex4.charAt(3 - j));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
            } else if (ch == '\\') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
                windowsName.append("//");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
            } else if (ch == '/') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
                windowsName.append('\\');
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
            } else if ((ch >= 'A') && (ch <='Z')) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1081
                windowsName.append('/').append(ch);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
                windowsName.append(ch);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
        return stringToByteArray(windowsName.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
     * Returns native handle for the top Windows node for this node.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
    private int rootNativeHandle() {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1093
        return (isUserNode()
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1094
                ? USER_ROOT_NATIVE_HANDLE
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1095
                : SYSTEM_ROOT_NATIVE_HANDLE);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
     * Returns this java string as a null-terminated byte array
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
    private static byte[] stringToByteArray(String str) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
        byte[] result = new byte[str.length()+1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1103
        for (int i = 0; i < str.length(); i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1104
            result[i] = (byte) str.charAt(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1105
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
        result[str.length()] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1109
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
     * Converts a null-terminated byte array to java string
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
    private static String byteArrayToString(byte[] array) {
30641
701f6f90dc0b 8074657: Missing space on a boundary of concatenated strings
igerasim
parents: 30043
diff changeset
  1114
        StringBuilder result = new StringBuilder();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
        for (int i = 0; i < array.length - 1; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
            result.append((char)array[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
        return result.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
   /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
    * Empty, never used implementation  of AbstractPreferences.flushSpi().
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
    */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
    protected void flushSpi() throws BackingStoreException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
        // assert false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
   /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
    * Empty, never used implementation  of AbstractPreferences.flushSpi().
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1130
    */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
    protected void syncSpi() throws BackingStoreException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
        // assert false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
3861
a98a057ec335 6882376: Add internal support for JRE implementation to eliminate the dependency on logging
mchung
parents: 2
diff changeset
  1135
    private static synchronized PlatformLogger logger() {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1136
        if (logger == null) {
3861
a98a057ec335 6882376: Add internal support for JRE implementation to eliminate the dependency on logging
mchung
parents: 2
diff changeset
  1137
            logger = PlatformLogger.getLogger("java.util.prefs");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
        return logger;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
}