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 #include "java_util_prefs_WindowsPreferences.h"
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
37 /*
38  * Declare library specific JNI_Onload entry if static build
39  */
40 DEF_STATIC_JNI_OnLoad
41 
42 JNIEXPORT jlongArray JNICALL
Java_java_util_prefs_WindowsPreferences_WindowsRegOpenKey(JNIEnv * env,jclass this_class,jlong hKey,jbyteArray lpSubKey,jint securityMask)43 Java_java_util_prefs_WindowsPreferences_WindowsRegOpenKey(JNIEnv* env,
44     jclass this_class, jlong hKey, jbyteArray lpSubKey, jint securityMask) {
45     char* str = (*env)->GetByteArrayElements(env, lpSubKey, NULL);
46     CHECK_NULL_RETURN(str, NULL);
47 
48     HKEY handle;
49     int errorCode = RegOpenKeyEx((HKEY) hKey, str, 0, securityMask, &handle);
50     (*env)->ReleaseByteArrayElements(env, lpSubKey, str, 0);
51 
52     jlong tmp[2];
53     tmp[0] = (jlong) handle;
54     tmp[1] = errorCode;
55     jlongArray result = (*env)->NewLongArray(env, 2);
56     if (result != NULL) {
57         (*env)->SetLongArrayRegion(env, result, 0, 2, tmp);
58     }
59     return result;
60 }
61 
62 JNIEXPORT jint JNICALL
Java_java_util_prefs_WindowsPreferences_WindowsRegCloseKey(JNIEnv * env,jclass this_class,jlong hKey)63 Java_java_util_prefs_WindowsPreferences_WindowsRegCloseKey(JNIEnv* env,
64     jclass this_class, jlong hKey) {
65     return (jint) RegCloseKey((HKEY) hKey);
66 };
67 
68 JNIEXPORT jlongArray JNICALL
Java_java_util_prefs_WindowsPreferences_WindowsRegCreateKeyEx(JNIEnv * env,jclass this_class,jlong hKey,jbyteArray lpSubKey)69 Java_java_util_prefs_WindowsPreferences_WindowsRegCreateKeyEx(JNIEnv* env,
70     jclass this_class, jlong hKey, jbyteArray lpSubKey) {
71     char* str = (*env)->GetByteArrayElements(env, lpSubKey, NULL);
72     CHECK_NULL_RETURN(str, NULL);
73 
74     HKEY handle;
75     DWORD lpdwDisposition;
76     int errorCode = RegCreateKeyEx((HKEY) hKey, str, 0, NULL,
77         REG_OPTION_NON_VOLATILE, KEY_READ,
78         NULL, &handle, &lpdwDisposition);
79     (*env)->ReleaseByteArrayElements(env, lpSubKey, str, 0);
80 
81     jlong tmp[3];
82     tmp[0] = (jlong) handle;
83     tmp[1] = errorCode;
84     tmp[2] = lpdwDisposition;
85     jlongArray result = (*env)->NewLongArray(env, 3);
86     if (result != NULL) {
87         (*env)->SetLongArrayRegion(env, result, 0, 3, tmp);
88     }
89     return result;
90 }
91 
92 JNIEXPORT jint JNICALL
Java_java_util_prefs_WindowsPreferences_WindowsRegDeleteKey(JNIEnv * env,jclass this_class,jlong hKey,jbyteArray lpSubKey)93 Java_java_util_prefs_WindowsPreferences_WindowsRegDeleteKey(JNIEnv* env,
94     jclass this_class, jlong hKey, jbyteArray lpSubKey) {
95     char* str = (*env)->GetByteArrayElements(env, lpSubKey, NULL);
96     CHECK_NULL_RETURN(str, -1);
97 
98     int result = RegDeleteKey((HKEY) hKey, str);
99     (*env)->ReleaseByteArrayElements(env, lpSubKey, str, 0);
100     return result;
101 
102 };
103 
104 JNIEXPORT jint JNICALL
Java_java_util_prefs_WindowsPreferences_WindowsRegFlushKey(JNIEnv * env,jclass this_class,jlong hKey)105 Java_java_util_prefs_WindowsPreferences_WindowsRegFlushKey(JNIEnv* env,
106     jclass this_class, jlong hKey) {
107     return RegFlushKey((HKEY) hKey);
108 }
109 
110 JNIEXPORT jbyteArray JNICALL
Java_java_util_prefs_WindowsPreferences_WindowsRegQueryValueEx(JNIEnv * env,jclass this_class,jlong hKey,jbyteArray valueName)111 Java_java_util_prefs_WindowsPreferences_WindowsRegQueryValueEx(JNIEnv* env,
112     jclass this_class, jlong hKey, jbyteArray valueName) {
113     char* valueNameStr = (*env)->GetByteArrayElements(env, valueName, NULL);
114     CHECK_NULL_RETURN(valueNameStr, NULL);
115 
116     DWORD valueType;
117     DWORD valueSize;
118     if (RegQueryValueEx((HKEY) hKey, valueNameStr, NULL, &valueType, NULL,
119         &valueSize) != ERROR_SUCCESS) {
120         (*env)->ReleaseByteArrayElements(env, valueName, valueNameStr, 0);
121         return NULL;
122     }
123 
124     char* buffer = (char*) malloc(valueSize);
125     if (buffer != NULL) {
126         if (RegQueryValueEx((HKEY) hKey, valueNameStr, NULL, &valueType, buffer,
127             &valueSize) != ERROR_SUCCESS) {
128             free(buffer);
129             (*env)->ReleaseByteArrayElements(env, valueName, valueNameStr, 0);
130             return NULL;
131         }
132     } else {
133         JNU_ThrowOutOfMemoryError(env, "native memory allocation failed");
134         (*env)->ReleaseByteArrayElements(env, valueName, valueNameStr, 0);
135         return NULL;
136     }
137 
138     jbyteArray result;
139     if (valueType == REG_SZ) {
140         result = (*env)->NewByteArray(env, valueSize);
141         if (result != NULL) {
142             (*env)->SetByteArrayRegion(env, result, 0, valueSize, buffer);
143         }
144     } else {
145         result = NULL;
146     }
147     free(buffer);
148     (*env)->ReleaseByteArrayElements(env, valueName, valueNameStr, 0);
149     return result;
150 }
151 
152 JNIEXPORT jint JNICALL
Java_java_util_prefs_WindowsPreferences_WindowsRegSetValueEx(JNIEnv * env,jclass this_class,jlong hKey,jbyteArray valueName,jbyteArray data)153 Java_java_util_prefs_WindowsPreferences_WindowsRegSetValueEx(JNIEnv* env,
154     jclass this_class, jlong hKey, jbyteArray valueName, jbyteArray data) {
155     if ((valueName == NULL) || (data == NULL)) {
156         return -1;
157     }
158     int size = (*env)->GetArrayLength(env, data);
159     char* dataStr = (*env)->GetByteArrayElements(env, data, NULL);
160     CHECK_NULL_RETURN(dataStr, -1);
161 
162     char* valueNameStr = (*env)->GetByteArrayElements(env, valueName, NULL);
163     int error_code = -1;
164     if (valueNameStr != NULL) {
165         error_code = RegSetValueEx((HKEY) hKey, valueNameStr, 0,
166             REG_SZ, dataStr, size);
167         (*env)->ReleaseByteArrayElements(env, valueName, valueNameStr, 0);
168     }
169     (*env)->ReleaseByteArrayElements(env, data, dataStr, 0);
170     return error_code;
171 }
172 
173 JNIEXPORT jint JNICALL
Java_java_util_prefs_WindowsPreferences_WindowsRegDeleteValue(JNIEnv * env,jclass this_class,jlong hKey,jbyteArray valueName)174 Java_java_util_prefs_WindowsPreferences_WindowsRegDeleteValue(JNIEnv* env,
175     jclass this_class, jlong hKey, jbyteArray valueName) {
176     if (valueName == NULL) {
177         return -1;
178     }
179     char* valueNameStr = (*env)->GetByteArrayElements(env, valueName, NULL);
180     CHECK_NULL_RETURN(valueNameStr, -1);
181 
182     int error_code = RegDeleteValue((HKEY) hKey, valueNameStr);
183     (*env)->ReleaseByteArrayElements(env, valueName, valueNameStr, 0);
184     return error_code;
185 }
186 
187 JNIEXPORT jlongArray JNICALL
Java_java_util_prefs_WindowsPreferences_WindowsRegQueryInfoKey(JNIEnv * env,jclass this_class,jlong hKey)188 Java_java_util_prefs_WindowsPreferences_WindowsRegQueryInfoKey(JNIEnv* env,
189     jclass this_class, jlong hKey) {
190     int subKeysNumber;
191     int maxSubKeyLength;
192     int valuesNumber;
193     int maxValueNameLength;
194     int errorCode = RegQueryInfoKey((HKEY) hKey, NULL, NULL, NULL,
195         &subKeysNumber, &maxSubKeyLength, NULL,
196         &valuesNumber, &maxValueNameLength,
197         NULL, NULL, NULL);
198 
199     jlong tmp[5];
200     tmp[0] = subKeysNumber;
201     tmp[1] = errorCode;
202     tmp[2] = valuesNumber;
203     tmp[3] = maxSubKeyLength;
204     tmp[4] = maxValueNameLength;
205     jintArray result = (*env)->NewLongArray(env, 5);
206     if (result != NULL) {
207         (*env)->SetLongArrayRegion(env, result, 0, 5, tmp);
208     }
209     return result;
210 }
211 
212 JNIEXPORT jbyteArray JNICALL
Java_java_util_prefs_WindowsPreferences_WindowsRegEnumKeyEx(JNIEnv * env,jclass this_class,jlong hKey,jint subKeyIndex,jint maxKeyLength)213 Java_java_util_prefs_WindowsPreferences_WindowsRegEnumKeyEx(JNIEnv* env,
214     jclass this_class, jlong hKey, jint subKeyIndex, jint maxKeyLength) {
215     int size = maxKeyLength;
216     char* buffer = (char*) malloc(maxKeyLength);
217     if (buffer == NULL) {
218         JNU_ThrowOutOfMemoryError(env, "native memory allocation failed");
219         return NULL;
220     }
221     if (RegEnumKeyEx((HKEY) hKey, subKeyIndex, buffer, &size, NULL, NULL,
222         NULL, NULL) != ERROR_SUCCESS) {
223         free(buffer);
224         return NULL;
225     }
226 
227     jbyteArray result = (*env)->NewByteArray(env, size + 1);
228     if (result != NULL) {
229         (*env)->SetByteArrayRegion(env, result, 0, size + 1, buffer);
230     }
231     free(buffer);
232     return result;
233 }
234 
235 JNIEXPORT jbyteArray JNICALL
Java_java_util_prefs_WindowsPreferences_WindowsRegEnumValue(JNIEnv * env,jclass this_class,jlong hKey,jint valueIndex,jint maxValueNameLength)236 Java_java_util_prefs_WindowsPreferences_WindowsRegEnumValue(JNIEnv* env,
237     jclass this_class, jlong hKey, jint valueIndex, jint maxValueNameLength) {
238     int size = maxValueNameLength;
239     char* buffer = (char*) malloc(maxValueNameLength);
240     if (buffer == NULL) {
241         JNU_ThrowOutOfMemoryError(env, "native memory allocation failed");
242         return NULL;
243     }
244 
245     int error_code = RegEnumValue((HKEY) hKey, valueIndex, buffer,
246         &size, NULL, NULL, NULL, NULL);
247     if (error_code != ERROR_SUCCESS) {
248         free(buffer);
249         return NULL;
250     }
251     jbyteArray result = (*env)->NewByteArray(env, size + 1);
252     if (result != NULL) {
253         (*env)->SetByteArrayRegion(env, result, 0, size + 1, buffer);
254     }
255     free(buffer);
256     return result;
257 }
258 
259 
260 #ifdef __cplusplus
261 }
262 #endif
263