1 /*
   2  * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #include <stdlib.h>
  27 #include <windows.h>
  28 #include "jni.h"
  29 #include "jni_util.h"
  30 #include "jvm.h"
  31 #ifdef __cplusplus
  32 extern "C" {
  33 #endif
  34 
  35 /*
  36  * Declare library specific JNI_Onload entry if static build
  37  */
  38 DEF_STATIC_JNI_OnLoad
  39 
  40 JNIEXPORT jlongArray JNICALL
  41 Java_java_util_prefs_WindowsPreferences_WindowsRegOpenKey(JNIEnv* env,
  42     jclass this_class, jlong hKey, jbyteArray lpSubKey, jint securityMask) {
  43     char* str = (*env)->GetByteArrayElements(env, lpSubKey, NULL);
  44     CHECK_NULL_RETURN(str, NULL);
  45 
  46     HKEY handle;
  47     int errorCode = RegOpenKeyEx((HKEY) hKey, str, 0, securityMask, &handle);
  48     (*env)->ReleaseByteArrayElements(env, lpSubKey, str, 0);
  49 
  50     jlong tmp[2];
  51     tmp[0] = (jlong) handle;
  52     tmp[1] = errorCode;
  53     jlongArray result = (*env)->NewLongArray(env, 2);
  54     if (result != NULL) {
  55         (*env)->SetLongArrayRegion(env, result, 0, 2, tmp);
  56     }
  57     return result;
  58 }
  59 
  60 JNIEXPORT jint JNICALL
  61 Java_java_util_prefs_WindowsPreferences_WindowsRegCloseKey(JNIEnv* env,
  62     jclass this_class, jlong hKey) {
  63     return (jint) RegCloseKey((HKEY) hKey);
  64 };
  65 
  66 JNIEXPORT jlongArray JNICALL
  67 Java_java_util_prefs_WindowsPreferences_WindowsRegCreateKeyEx(JNIEnv* env,
  68     jclass this_class, jlong hKey, jbyteArray lpSubKey) {
  69     char* str = (*env)->GetByteArrayElements(env, lpSubKey, NULL);
  70     CHECK_NULL_RETURN(str, NULL);
  71 
  72     HKEY handle;
  73     DWORD lpdwDisposition;
  74     int errorCode = RegCreateKeyEx((HKEY) hKey, str, 0, NULL,
  75         REG_OPTION_NON_VOLATILE, KEY_READ,
  76         NULL, &handle, &lpdwDisposition);
  77     (*env)->ReleaseByteArrayElements(env, lpSubKey, str, 0);
  78 
  79     jlong tmp[3];
  80     tmp[0] = (jlong) handle;
  81     tmp[1] = errorCode;
  82     tmp[2] = lpdwDisposition;
  83     jlongArray result = (*env)->NewLongArray(env, 3);
  84     if (result != NULL) {
  85         (*env)->SetLongArrayRegion(env, result, 0, 3, tmp);
  86     }
  87     return result;
  88 }
  89 
  90 JNIEXPORT jint JNICALL
  91 Java_java_util_prefs_WindowsPreferences_WindowsRegDeleteKey(JNIEnv* env,
  92     jclass this_class, jlong hKey, jbyteArray lpSubKey) {
  93     char* str = (*env)->GetByteArrayElements(env, lpSubKey, NULL);
  94     CHECK_NULL_RETURN(str, -1);
  95 
  96     int result = RegDeleteKey((HKEY) hKey, str);
  97     (*env)->ReleaseByteArrayElements(env, lpSubKey, str, 0);
  98     return result;
  99 
 100 };
 101 
 102 JNIEXPORT jint JNICALL
 103 Java_java_util_prefs_WindowsPreferences_WindowsRegFlushKey(JNIEnv* env,
 104     jclass this_class, jlong hKey) {
 105     return RegFlushKey((HKEY) hKey);
 106 }
 107 
 108 JNIEXPORT jbyteArray JNICALL
 109 Java_java_util_prefs_WindowsPreferences_WindowsRegQueryValueEx(JNIEnv* env,
 110     jclass this_class, jlong hKey, jbyteArray valueName) {
 111     char* valueNameStr = (*env)->GetByteArrayElements(env, valueName, NULL);
 112     CHECK_NULL_RETURN(valueNameStr, NULL);
 113 
 114     DWORD valueType;
 115     DWORD valueSize;
 116     if (RegQueryValueEx((HKEY) hKey, valueNameStr, NULL, &valueType, NULL,
 117         &valueSize) != ERROR_SUCCESS) {
 118         (*env)->ReleaseByteArrayElements(env, valueName, valueNameStr, 0);
 119         return NULL;
 120     }
 121 
 122     char* buffer = (char*) malloc(valueSize);
 123     if (buffer != NULL) {
 124         if (RegQueryValueEx((HKEY) hKey, valueNameStr, NULL, &valueType, buffer,
 125             &valueSize) != ERROR_SUCCESS) {
 126             free(buffer);
 127             (*env)->ReleaseByteArrayElements(env, valueName, valueNameStr, 0);
 128             return NULL;
 129         }
 130     } else {
 131         JNU_ThrowOutOfMemoryError(env, "native memory allocation failed");
 132         (*env)->ReleaseByteArrayElements(env, valueName, valueNameStr, 0);
 133         return NULL;
 134     }
 135 
 136     jbyteArray result;
 137     if (valueType == REG_SZ) {
 138         result = (*env)->NewByteArray(env, valueSize);
 139         if (result != NULL) {
 140             (*env)->SetByteArrayRegion(env, result, 0, valueSize, buffer);
 141         }
 142     } else {
 143         result = NULL;
 144     }
 145     free(buffer);
 146     (*env)->ReleaseByteArrayElements(env, valueName, valueNameStr, 0);
 147     return result;
 148 }
 149 
 150 JNIEXPORT jint JNICALL
 151 Java_java_util_prefs_WindowsPreferences_WindowsRegSetValueEx(JNIEnv* env,
 152     jclass this_class, jlong hKey, jbyteArray valueName, jbyteArray data) {
 153     if ((valueName == NULL) || (data == NULL)) {
 154         return -1;
 155     }
 156     int size = (*env)->GetArrayLength(env, data);
 157     char* dataStr = (*env)->GetByteArrayElements(env, data, NULL);
 158     CHECK_NULL_RETURN(dataStr, -1);
 159 
 160     char* valueNameStr = (*env)->GetByteArrayElements(env, valueName, NULL);
 161     int error_code = -1;
 162     if (valueNameStr != NULL) {
 163         error_code = RegSetValueEx((HKEY) hKey, valueNameStr, 0,
 164             REG_SZ, dataStr, size);
 165         (*env)->ReleaseByteArrayElements(env, valueName, valueNameStr, 0);
 166     }
 167     (*env)->ReleaseByteArrayElements(env, data, dataStr, 0);
 168     return error_code;
 169 }
 170 
 171 JNIEXPORT jint JNICALL
 172 Java_java_util_prefs_WindowsPreferences_WindowsRegDeleteValue(JNIEnv* env,
 173     jclass this_class, jlong hKey, jbyteArray valueName) {
 174     if (valueName == NULL) {
 175         return -1;
 176     }
 177     char* valueNameStr = (*env)->GetByteArrayElements(env, valueName, NULL);
 178     CHECK_NULL_RETURN(valueNameStr, -1);
 179 
 180     int error_code = RegDeleteValue((HKEY) hKey, valueNameStr);
 181     (*env)->ReleaseByteArrayElements(env, valueName, valueNameStr, 0);
 182     return error_code;
 183 }
 184 
 185 JNIEXPORT jlongArray JNICALL
 186 Java_java_util_prefs_WindowsPreferences_WindowsRegQueryInfoKey(JNIEnv* env,
 187     jclass this_class, jlong hKey) {
 188     int subKeysNumber;
 189     int maxSubKeyLength;
 190     int valuesNumber;
 191     int maxValueNameLength;
 192     int errorCode = RegQueryInfoKey((HKEY) hKey, NULL, NULL, NULL,
 193         &subKeysNumber, &maxSubKeyLength, NULL,
 194         &valuesNumber, &maxValueNameLength,
 195         NULL, NULL, NULL);
 196 
 197     jlong tmp[5];
 198     tmp[0] = subKeysNumber;
 199     tmp[1] = errorCode;
 200     tmp[2] = valuesNumber;
 201     tmp[3] = maxSubKeyLength;
 202     tmp[4] = maxValueNameLength;
 203     jintArray result = (*env)->NewLongArray(env, 5);
 204     if (result != NULL) {
 205         (*env)->SetLongArrayRegion(env, result, 0, 5, tmp);
 206     }
 207     return result;
 208 }
 209 
 210 JNIEXPORT jbyteArray JNICALL
 211 Java_java_util_prefs_WindowsPreferences_WindowsRegEnumKeyEx(JNIEnv* env,
 212     jclass this_class, jlong hKey, jint subKeyIndex, jint maxKeyLength) {
 213     int size = maxKeyLength;
 214     char* buffer = (char*) malloc(maxKeyLength);
 215     if (buffer == NULL) {
 216         JNU_ThrowOutOfMemoryError(env, "native memory allocation failed");
 217         return NULL;
 218     }
 219     if (RegEnumKeyEx((HKEY) hKey, subKeyIndex, buffer, &size, NULL, NULL,
 220         NULL, NULL) != ERROR_SUCCESS) {
 221         free(buffer);
 222         return NULL;
 223     }
 224 
 225     jbyteArray result = (*env)->NewByteArray(env, size + 1);
 226     if (result != NULL) {
 227         (*env)->SetByteArrayRegion(env, result, 0, size + 1, buffer);
 228     }
 229     free(buffer);
 230     return result;
 231 }
 232 
 233 JNIEXPORT jbyteArray JNICALL
 234 Java_java_util_prefs_WindowsPreferences_WindowsRegEnumValue(JNIEnv* env,
 235     jclass this_class, jlong hKey, jint valueIndex, jint maxValueNameLength) {
 236     int size = maxValueNameLength;
 237     char* buffer = (char*) malloc(maxValueNameLength);
 238     if (buffer == NULL) {
 239         JNU_ThrowOutOfMemoryError(env, "native memory allocation failed");
 240         return NULL;
 241     }
 242 
 243     int error_code = RegEnumValue((HKEY) hKey, valueIndex, buffer,
 244         &size, NULL, NULL, NULL, NULL);
 245     if (error_code != ERROR_SUCCESS) {
 246         free(buffer);
 247         return NULL;
 248     }
 249     jbyteArray result = (*env)->NewByteArray(env, size + 1);
 250     if (result != NULL) {
 251         (*env)->SetByteArrayRegion(env, result, 0, size + 1, buffer);
 252     }
 253     free(buffer);
 254     return result;
 255 }
 256 
 257 
 258 #ifdef __cplusplus
 259 }
 260 #endif