Skip to content

Commit

Permalink
Add fix for issue #135 in Advapi32Util (reading empty values)
Browse files Browse the repository at this point in the history
With this fix it is possible to read values from registry of the following
types even when the size of the value is 0:

REG_SZ
REG_EXPAND_SZ
REG_MULTI_SZ
REG_NONE
REG_BINARY (fixed by earlier committer)

Advapi32UtilTest updated with unit test triggering the bug.
  • Loading branch information
danwi committed Oct 8, 2012
1 parent c1a7fd7 commit 018ad7f
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 2 deletions.
24 changes: 22 additions & 2 deletions contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -1262,8 +1262,28 @@ public static TreeMap<String, Object> registryGetValues(HKEY hKey) {

String nameString = Native.toString(name);

if(lpcbData.getValue() == 0 && lpType.getValue() == WinNT.REG_BINARY) {
keyValues.put(nameString, new byte[0]);
if(lpcbData.getValue() == 0) {
switch (lpType.getValue()) {
case WinNT.REG_BINARY: {
keyValues.put(nameString, new byte[0]);
break;
}
case WinNT.REG_SZ:
case WinNT.REG_EXPAND_SZ: {
keyValues.put(nameString, new char[0]);
break;
}
case WinNT.REG_MULTI_SZ: {
keyValues.put(nameString, new String[0]);
break;
}
case WinNT.REG_NONE: {
keyValues.put(nameString, null);
break;
}
default:
throw new RuntimeException("Unsupported empty type: " + lpType.getValue());
}
continue;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
import com.sun.jna.platform.win32.WinNT.PSID;
import com.sun.jna.platform.win32.WinNT.SID_NAME_USE;
import com.sun.jna.platform.win32.WinNT.WELL_KNOWN_SID_TYPE;
import com.sun.jna.platform.win32.WinReg.HKEY;
import com.sun.jna.platform.win32.WinReg.HKEYByReference;

/**
* @author dblock[at]dblock[dot]org
Expand Down Expand Up @@ -316,6 +318,46 @@ public void testRegistryGetValues() {
assertEquals(0, stringsRead.length);
Advapi32Util.registryDeleteKey(WinReg.HKEY_CURRENT_USER, "Software", "JNA");
}

public void testRegistryGetEmptyValues() {
HKEY root = WinReg.HKEY_CURRENT_USER;
String keyPath = "Software\\JNA";
Advapi32Util.registryCreateKey(root, "Software", "JNA");
doTestRegistryGetEmptyValues(root, keyPath, WinNT.REG_BINARY);
doTestRegistryGetEmptyValues(root, keyPath, WinNT.REG_EXPAND_SZ);
doTestRegistryGetEmptyValues(root, keyPath, WinNT.REG_MULTI_SZ);
doTestRegistryGetEmptyValues(root, keyPath, WinNT.REG_NONE);
doTestRegistryGetEmptyValues(root, keyPath, WinNT.REG_SZ);
Advapi32Util.registryDeleteKey(root, "Software", "JNA");
}

private void doTestRegistryGetEmptyValues(HKEY root, String keyPath, int valueType) {
String valueName = "EmptyValue";
registrySetEmptyValue(root, keyPath, valueName, valueType);
Map<String, Object> values = Advapi32Util.registryGetValues(root, keyPath);
assertEquals(1, values.size());
assertTrue(values.containsKey(valueName));
}

private static void registrySetEmptyValue(HKEY root, String keyPath, String name, final int valueType) {
HKEYByReference phkKey = new HKEYByReference();
int rc = Advapi32.INSTANCE.RegOpenKeyEx(root, keyPath, 0, WinNT.KEY_READ | WinNT.KEY_WRITE, phkKey);
if (rc != W32Errors.ERROR_SUCCESS) {
throw new Win32Exception(rc);
}
try {
char[] data = new char[0];
rc = Advapi32.INSTANCE.RegSetValueEx(phkKey.getValue(), name, 0, valueType, data, 0);
if (rc != W32Errors.ERROR_SUCCESS) {
throw new Win32Exception(rc);
}
} finally {
rc = Advapi32.INSTANCE.RegCloseKey(phkKey.getValue());
if (rc != W32Errors.ERROR_SUCCESS) {
throw new Win32Exception(rc);
}
}
}

public void testIsWellKnownSid() {
String everyoneString = "S-1-1-0";
Expand Down

0 comments on commit 018ad7f

Please sign in to comment.