Skip to content

Commit

Permalink
Added SetupDiOpenDevRegKey , SetupDiEnumDeviceInfo and related
Browse files Browse the repository at this point in the history
constants to `com.sun.jna.platform.win32.SetupApi`
  • Loading branch information
Christian Schwarz authored and dblock committed Apr 6, 2015
1 parent ccea051 commit 0b47d1e
Show file tree
Hide file tree
Showing 3 changed files with 224 additions and 16 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Features
* [#400](https://github.com/twall/jna/pull/400): Added process-specific access rights constants in `com.sun.jna.platform.win32.WinNT` - [@PAX523](https://github.com/PAX523).
* [#400](https://github.com/twall/jna/pull/400): Added specific constants for request of icon settings in `com.sun.jna.platform.win32.WinUser` - [@PAX523](https://github.com/PAX523).
* [#400](https://github.com/twall/jna/pull/400): Added constants for `GetClassLong`, `SendMessageTimeout` and `GetIconInfo` in `com.sun.jna.platform.win32.WinUser` - [@PAX523](https://github.com/PAX523).
* [#419](https://github.com/twall/jna/pull/419): Added `SetupDiOpenDevRegKey` , `SetupDiEnumDeviceInfo` and related constants to `com.sun.jna.platform.win32.SetupApi` - [@ChristianSchwarz](https://github.com/ChristianSchwarz).

Bug Fixes
---------
Expand Down
169 changes: 153 additions & 16 deletions contrib/platform/src/com/sun/jna/platform/win32/SetupApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.Guid.GUID;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.platform.win32.WinReg.HKEY;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

/**
* The interface for the w32 setup API.
* @author Christian Schwarz
*/
public interface SetupApi extends StdCallLibrary {

Expand All @@ -31,49 +35,98 @@ public interface SetupApi extends StdCallLibrary {
/**
* The GUID_DEVINTERFACE_DISK device interface class is defined for hard disk storage devices.
*/
public static Guid.GUID GUID_DEVINTERFACE_DISK = new Guid.GUID(new byte[]
{
0x07, 0x63, (byte) 0xf5, 0x53, (byte) 0xbf, (byte) 0xb6, (byte) 0xd0, 0x11,
(byte) 0x94, (byte) 0xf2, 0x00, (byte) 0xa0, (byte) 0xc9, (byte) 0x1e, (byte) 0xfb, (byte) 0x8b
});

GUID GUID_DEVINTERFACE_DISK = new GUID("53F56307-B6BF-11D0-94F2-00A0C91EFB8B");


/**
* Drivers for serial ports register instances of this device interface
* class to notify the operating system and applications of the presence of
* COM ports.
*/
GUID GUID_DEVINTERFACE_COMPORT = new GUID("86E0D1E0-8089-11D0-9CE4-08003E301F73");

/**
* Return only the device that is associated with the system default device interface, if one is set, for the
* specified device interface classes.
*/
public int DIGCF_DEFAULT = 0x1;
int DIGCF_DEFAULT = 0x1;

/**
* Return only devices that are currently present in a system.
*/
public int DIGCF_PRESENT = 0x2;
int DIGCF_PRESENT = 0x2;

/**
* Return a list of installed devices for all device setup classes or all device interface classes.
*/
public int DIGCF_ALLCLASSES = 0x4;
int DIGCF_ALLCLASSES = 0x4;

/**
* Return only devices that are a part of the current hardware profile.
*/
public int DIGCF_PROFILE = 0x8;
int DIGCF_PROFILE = 0x8;

/**
* Return devices that support device interfaces for the specified device interface classes. This flag must be set
* in the Flags parameter if the Enumerator parameter specifies a device instance ID.
*/
public int DIGCF_DEVICEINTERFACE = 0x10;
int DIGCF_DEVICEINTERFACE = 0x10;

/**
* (Windows XP and later) The function retrieves the device's current removal policy as a DWORD that contains one of
* the CM_REMOVAL_POLICY_Xxx values that are defined in Cfgmgr32.h.
*/
public int SPDRP_REMOVAL_POLICY = 0x0000001F;
int SPDRP_REMOVAL_POLICY = 0x0000001F;

/**
* Removable.
*/
public int CM_DEVCAP_REMOVABLE = 0x00000004;
int CM_DEVCAP_REMOVABLE = 0x00000004;


/** make change in all hardware profiles */
int DICS_FLAG_GLOBAL = 0x00000001;
/** make change in specified profile only */
int DICS_FLAG_CONFIGSPECIFIC = 0x00000002;
/** 1 or more hardware profile-specific changes to follow. */
int DICS_FLAG_CONFIGGENERAL = 0x00000004;

/**
* Open/Create/Delete device key.
*
* @see SetupDiCreateDevRegKey , SetupDiOpenDevRegKey, and
* SetupDiDeleteDevRegKey.
*/

int DIREG_DEV = 0x00000001;
/**
* Open/Create/Delete driver key
*
* @see SetupDiCreateDevRegKey, SetupDiOpenDevRegKey, and
* SetupDiDeleteDevRegKey.
*/

int DIREG_DRV = 0x00000002;
/**
* Delete both driver and Device key
*
* @see SetupDiCreateDevRegKey, SetupDiOpenDevRegKey, and
* SetupDiDeleteDevRegKey.
*/

int DIREG_BOTH = 0x00000004;

/**
* DeviceDesc (R/W)
* <p>
* Device registry property codes (Codes marked as read-only (R) may only be
* used for SetupDiGetDeviceRegistryProperty)
* <p>
* These values should cover the same set of registry properties as defined
* by the CM_DRP codes in cfgmgr32.h.
*/
int SPDRP_DEVICEDESC = 0x00000000;


/**
* The SetupDiGetClassDevs function returns a handle to a device information set that contains requested device
Expand Down Expand Up @@ -236,10 +289,94 @@ boolean SetupDiGetDeviceInterfaceDetail(WinNT.HANDLE hDevInfo,
* ERROR_INVALID_DATA error code if the requested property does not exist for a device or if the property data is
* not valid.
*/
boolean SetupDiGetDeviceRegistryProperty(WinNT.HANDLE DeviceInfoSet, SP_DEVINFO_DATA DeviceInfoData,
boolean SetupDiGetDeviceRegistryProperty(HANDLE DeviceInfoSet, SP_DEVINFO_DATA DeviceInfoData,
int Property, IntByReference PropertyRegDataType, Pointer PropertyBuffer, int PropertyBufferSize,
IntByReference RequiredSize);

/**
* The SetupDiOpenDevRegKey function opens a registry key for device-specific configuration information.
* <p>
* Depending on the value that is passed in the samDesired parameter, it might be necessary for the caller of this
* function to be a member of the Administrators group.
* <p>
* Close the handle returned from this function by calling RegCloseKey.
* <p>
* The specified device instance must be registered before this function is called. However, be aware that the
* operating system automatically registers PnP device instances. For information about how to register non-PnP
* device instances, see SetupDiRegisterDeviceInfo.
*
* @param deviceInfoSet
* A handle to the device information set that contains a device information element that represents the
* device for which to open a registry key.
* @param deviceInfoData
* A pointer to an {@link SP_DEVINFO_DATA} structure that specifies the device information element in
* DeviceInfoSet.
* @param scope
* he scope of the registry key to open. The scope determines where the information is stored. The scope
* can be global or specific to a hardware profile. The scope is specified by one of the following
* values:
* <ul>
* <li>DICS_FLAG_GLOBAL Open a key to store global configuration information. This information is not
* specific to a particular hardware profile. This opens a key that is rooted at HKEY_LOCAL_MACHINE. The
* exact key opened depends on the value of the KeyType parameter. <li>DICS_FLAG_CONFIGSPECIFIC Open a
* key to store hardware profile-specific configuration information. This key is rooted at one of the
* hardware-profile specific branches, instead of HKEY_LOCAL_MACHINE. The exact key opened depends on the
* value of the KeyType parameter.
* </ul>
* @param hwProfile
* A hardware profile value, which is set as follows:
* <ul>
* <li>If Scope is set to DICS_FLAG_CONFIGSPECIFIC, HwProfile specifies the hardware profile of the key
* that is to be opened. <li>If HwProfile is 0, the key for the current hardware profile is opened. <li>
* If Scope is DICS_FLAG_GLOBAL, HwProfile is ignored.
* </ul>
* @param keyType
* The type of registry storage key to open, which can be one of the following values:
* <ul>
* <li> {@link #DIREG_DEV} Open a hardware key for the device. <li>{@link #DIREG_DRV} Open a software key
* for the device. For more information about a device's hardware and software keys, see Registry Trees
* and Keys for Devices and Drivers.
* </ul>
* @param samDesired
* The registry security access that is required for the requested key. For information about registry
* security access values of type REGSAM, see the Microsoft Windows SDK documentation.
* @return If the function is successful, it returns a handle to an opened registry key where private configuration
* data about this device instance can be stored/retrieved.
* <p>
* If the function fails, it returns INVALID_HANDLE_VALUE. To get extended error information, call
* GetLastError.
*/
HKEY SetupDiOpenDevRegKey(HANDLE deviceInfoSet, SP_DEVINFO_DATA deviceInfoData, int scope, int hwProfile, int keyType, int samDesired);

/**
* The SetupDiEnumDeviceInfo function returns a {@link SP_DEVINFO_DATA} structure that specifies a device
* information element in a device information set.
* <p>
* <b>Remarks</b><br>
* Repeated calls to this function return a device information element for a different device. This function can be
* called repeatedly to get information about all devices in the device information set.
* <p>
* To enumerate device information elements, an installer should initially call SetupDiEnumDeviceInfo with the
* MemberIndex parameter set to 0. The installer should then increment MemberIndex and call SetupDiEnumDeviceInfo
* until there are no more values (the function fails and a call to GetLastError returns ERROR_NO_MORE_ITEMS).
* <p>
* Call SetupDiEnumDeviceInterfaces to get a context structure for a device interface element (versus a device
* information element).
*
*
* @param deviceInfoSet
* A handle to the device information set for which to return an {@link SP_DEVINFO_DATA} structure that
* represents a device information element.
* @param memberIndex
* A zero-based index of the device information element to retrieve.
* @param deviceInfoData
* A pointer to an SP_DEVINFO_DATA structure to receive information about an enumerated device
* information element.
* @return The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be
* retrieved with a call to GetLastError.
*/
boolean SetupDiEnumDeviceInfo(HANDLE deviceInfoSet, int memberIndex, SP_DEVINFO_DATA deviceInfoData);

/**
* An SP_DEVICE_INTERFACE_DATA structure defines a device interface in a device information set.
*/
Expand Down Expand Up @@ -286,7 +423,7 @@ public SP_DEVICE_INTERFACE_DATA(Pointer memory) {
*/
public Pointer Reserved;

protected List getFieldOrder() {
protected List<String> getFieldOrder() {
return Arrays.asList(new String[] { "cbSize", "InterfaceClassGuid", "Flags", "Reserved" });
}
}
Expand Down Expand Up @@ -338,7 +475,7 @@ public SP_DEVINFO_DATA(Pointer memory) {
*/
public Pointer Reserved;

protected List getFieldOrder() {
protected List<String> getFieldOrder() {
return Arrays.asList(new String[] { "cbSize", "InterfaceClassGuid", "DevInst", "Reserved" });
}
}
Expand Down
70 changes: 70 additions & 0 deletions contrib/platform/test/com/sun/jna/platform/win32/SetupApiTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.sun.jna.platform.win32;

import static com.sun.jna.Native.getLastError;
import static com.sun.jna.platform.win32.SetupApi.DICS_FLAG_GLOBAL;
import static com.sun.jna.platform.win32.SetupApi.DIGCF_ALLCLASSES;
import static com.sun.jna.platform.win32.SetupApi.DIGCF_DEVICEINTERFACE;
import static com.sun.jna.platform.win32.SetupApi.DIGCF_PRESENT;
import static com.sun.jna.platform.win32.SetupApi.DIREG_DEV;
import static com.sun.jna.platform.win32.SetupApi.GUID_DEVINTERFACE_COMPORT;
import static com.sun.jna.platform.win32.WinBase.INVALID_HANDLE_VALUE;
import static com.sun.jna.platform.win32.WinError.ERROR_NO_MORE_ITEMS;
import static com.sun.jna.platform.win32.WinNT.KEY_QUERY_VALUE;
import junit.framework.TestCase;

import com.sun.jna.platform.win32.SetupApi.SP_DEVINFO_DATA;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.platform.win32.WinReg.HKEY;

public class SetupApiTest extends TestCase {
/**
* member index for the first device, see {@link SetupApi#SetupDiEnumDeviceInfo(HANDLE, int, SP_DEVINFO_DATA)}
*/
private static final int FIRST_MEMBER = 0;

public static void main(String[] args) {
junit.textui.TestRunner.run(SetupApiTest.class);
}

/**
* Tests the mapping of {@link SetupApi#SetupDiOpenDevRegKey(HANDLE, SP_DEVINFO_DATA, int, int, int, int)} .
* <p>
* The test pass if SetupDiOpenDevRegKey(..) returns a valid {@link HKEY} pointing to the first found device on the current machine.
* <p>
* NOTE: We only test the mapping of SetupDiOpenDevRegKey(..), not it's functionality.
*/
public void testSetupDiOpenDevRegKey() {
// hDevInfoSet repesents a list of installed devices for all device
// setup classes or all device interface classes
HANDLE hDevInfoSet = SetupApi.INSTANCE.SetupDiGetClassDevs(null, null, null, DIGCF_ALLCLASSES);
assertTrue(hDevInfoSet != INVALID_HANDLE_VALUE);

SP_DEVINFO_DATA devInfo = new SP_DEVINFO_DATA();
// there must be least one device (drive,processor,pci,usb,...) on the
// current machine
assertTrue(SetupApi.INSTANCE.SetupDiEnumDeviceInfo(hDevInfoSet, FIRST_MEMBER, devInfo));

HKEY hDeviceKey = SetupApi.INSTANCE.SetupDiOpenDevRegKey(hDevInfoSet, devInfo, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
assertTrue(hDeviceKey != INVALID_HANDLE_VALUE);

Advapi32.INSTANCE.RegCloseKey(hDeviceKey);
}

/**
* Tests the mapping of {@link SetupApi#SetupDiEnumDeviceInfo(HANDLE, int, SP_DEVINFO_DATA)} .
* <p>
* There are 2 different results possible, depending availability of an COM-Port on the current machine:
* <ul>
* <li>If the current machine has no COM-Port the method must fail and the the last error indicate that there are no more values / COM-Ports.
* <li>If the current machine has at least one COM-Port the method must succeed. The test pass if no exception is thrown.
* </ul>
*/
public void testSetupDiEnumDeviceInfo() {
HANDLE hDevInfoSet = SetupApi.INSTANCE.SetupDiGetClassDevs(GUID_DEVINTERFACE_COMPORT, null, null, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
SP_DEVINFO_DATA devInfo = new SP_DEVINFO_DATA();
boolean succeed = SetupApi.INSTANCE.SetupDiEnumDeviceInfo(hDevInfoSet, FIRST_MEMBER, devInfo);
boolean hasNoMoreItems = (getLastError() == ERROR_NO_MORE_ITEMS);

assertTrue(succeed || hasNoMoreItems);
}
}

0 comments on commit 0b47d1e

Please sign in to comment.