/*
* Copyright 2010 NCHOVY
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.krakenapps.winapi;
import java.nio.charset.Charset;
import java.util.Date;
import org.krakenapps.winapi.impl.ObjectRef;
import org.krakenapps.winapi.impl.IntegerRef;
public class RegistryKey {
static {
System.loadLibrary("winapi");
}
private int hkey;
public static RegistryKey currentUser() {
return new RegistryKey(0x80000001);
}
public static RegistryKey localMachine() {
return new RegistryKey(0x80000002);
}
public static RegistryKey users() {
return new RegistryKey(0x80000003);
}
public static RegistryKey performanceData() {
return new RegistryKey(0x80000004);
}
private RegistryKey(int hkey) {
this.hkey = hkey;
}
public int getSubKeyCount() {
QueryInfo info = queryInfoKey();
return info.subKeyCount;
}
public int getValueCount() {
QueryInfo info = queryInfoKey();
return info.valuesCount;
}
public String[] getSubKeyNames() {
QueryInfo info = queryInfoKey();
ObjectRef name = new ObjectRef();
ObjectRef lastWriteTime = new ObjectRef();
String[] names = new String[info.subKeyCount];
for (int i = 0; i < info.subKeyCount; i++) {
RegEnumKeyEx(hkey, i, name, info.maxSubKeyLen, lastWriteTime);
names[i] = (String) name.value;
}
return names;
}
public String[] getValueNames() {
QueryInfo info = queryInfoKey();
ObjectRef name = new ObjectRef();
String[] names = new String[info.valuesCount];
for (int i = 0; i < info.valuesCount; i++) {
RegEnumValue(hkey, i, name, info.maxValueNameLen);
names[i] = (String) name.value;
}
return names;
}
private QueryInfo queryInfoKey() {
IntegerRef subKeyCount = new IntegerRef();
IntegerRef maxSubKeyLen = new IntegerRef();
IntegerRef maxClassLen = new IntegerRef();
IntegerRef valuesCount = new IntegerRef();
IntegerRef maxValueNameLen = new IntegerRef();
IntegerRef maxValueLen = new IntegerRef();
IntegerRef securityDescriptorSize = new IntegerRef();
ObjectRef lastWriteTime = new ObjectRef();
RegQueryInfoKey(hkey, subKeyCount, maxSubKeyLen, maxClassLen, valuesCount, maxValueNameLen, maxValueLen,
securityDescriptorSize, lastWriteTime);
QueryInfo i = new QueryInfo();
i.subKeyCount = subKeyCount.value;
i.maxSubKeyLen = maxSubKeyLen.value;
i.maxClassLen = maxClassLen.value;
i.valuesCount = valuesCount.value;
i.maxValueNameLen = maxValueNameLen.value;
i.maxValueLen = maxValueLen.value;
i.securityDescriptorSize = securityDescriptorSize.value;
return i;
}
public Object getValue(String name) {
IntegerRef type = new IntegerRef();
ObjectRef buffer = new ObjectRef();
RegQueryValueEx(hkey, name, type, buffer);
byte[] b = (byte[]) buffer.value;
if (type.value == 0) {
// REG_NONE
return null;
} else if (type.value == 1) {
// REG_SZ
return new String(b, 0, b.length - 2, Charset.forName("UTF-16LE"));
} else if (type.value == 2) {
// REG_EXPAND_SZ
return new String(b, 0, b.length - 2, Charset.forName("UTF-16LE"));
} else if (type.value == 3) {
// REG_BINARY
return b;
} else if (type.value == 4) {
// REG_DWORD
return ((b[3] << 24) & 0xFF000000) | ((b[2] << 16) & 0xFF0000) | ((b[1] << 8) & 0xFF00) | (b[0] & 0xFF);
} else if (type.value == 5) {
// REG_DWORD_BIG_ENDIAN
return ((b[0] << 24) & 0xFF000000) | ((b[1] << 16) & 0xFF0000) | ((b[2] << 8) & 0xFF00) | (b[3] & 0xFF);
} else if (type.value == 6) {
// REG_LINK
} else if (type.value == 7) {
// REG_MULTI_SZ
} else if (type.value == 8) {
// REG_RESOURCE_LIST
} else if (type.value == 9) {
// REG_FULL_RESOURCE_DESCRIPTOR
} else if (type.value == 10) {
// REG_RESOURCE_REQUIREMENTS_LIST
} else if (type.value == 11) {
// QWORD
}
return new UnsupportedOperationException("reg type: " + type.value);
}
public RegistryKey openSubKey(String path) {
IntegerRef ref = new IntegerRef();
RegOpenKeyEx(hkey, path, 0, ref);
return new RegistryKey(ref.value);
}
public void close() {
RegCloseKey(hkey);
}
@Override
public String toString() {
return "0x" + Integer.toHexString(hkey);
}
private native int RegOpenKeyEx(int hkey, String subKey, int samDesired, IntegerRef hkeyResult);
private native int RegQueryValueEx(int hkey, String valueName, IntegerRef type, ObjectRef buffer);
private native int RegCloseKey(int hkey);
private native int RegQueryInfoKey(int hkey, IntegerRef subKeyCount, IntegerRef maxSubKeyLen,
IntegerRef maxClassLen, IntegerRef valuesCount, IntegerRef maxValueNameLen, IntegerRef maxValueLen,
IntegerRef securityDescriptorSize, ObjectRef lastWriteTime);
private native int RegEnumKeyEx(int hkey, int index, ObjectRef name, int maxNameLen, ObjectRef lastWriteTime);
private native int RegEnumValue(int hkey, int index, ObjectRef name, int maxNameLen);
private static class QueryInfo {
int subKeyCount;
int maxSubKeyLen;
int maxClassLen;
int valuesCount;
int maxValueNameLen;
int maxValueLen;
int securityDescriptorSize;
Date lastWriteTime;
}
}