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