Skip to content

Commit 0b47d1e

Browse files
Christian Schwarzdblock
Christian Schwarz
authored andcommitted
Added SetupDiOpenDevRegKey , SetupDiEnumDeviceInfo and related
constants to `com.sun.jna.platform.win32.SetupApi`
1 parent ccea051 commit 0b47d1e

File tree

3 files changed

+224
-16
lines changed

3 files changed

+224
-16
lines changed

CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Features
3737
* [#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).
3838
* [#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).
3939
* [#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).
40+
* [#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).
4041

4142
Bug Fixes
4243
---------

contrib/platform/src/com/sun/jna/platform/win32/SetupApi.java

+153-16
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,16 @@
1616
import com.sun.jna.Native;
1717
import com.sun.jna.Pointer;
1818
import com.sun.jna.Structure;
19+
import com.sun.jna.platform.win32.Guid.GUID;
20+
import com.sun.jna.platform.win32.WinNT.HANDLE;
21+
import com.sun.jna.platform.win32.WinReg.HKEY;
1922
import com.sun.jna.ptr.IntByReference;
2023
import com.sun.jna.win32.StdCallLibrary;
2124
import com.sun.jna.win32.W32APIOptions;
2225

2326
/**
2427
* The interface for the w32 setup API.
28+
* @author Christian Schwarz
2529
*/
2630
public interface SetupApi extends StdCallLibrary {
2731

@@ -31,49 +35,98 @@ public interface SetupApi extends StdCallLibrary {
3135
/**
3236
* The GUID_DEVINTERFACE_DISK device interface class is defined for hard disk storage devices.
3337
*/
34-
public static Guid.GUID GUID_DEVINTERFACE_DISK = new Guid.GUID(new byte[]
35-
{
36-
0x07, 0x63, (byte) 0xf5, 0x53, (byte) 0xbf, (byte) 0xb6, (byte) 0xd0, 0x11,
37-
(byte) 0x94, (byte) 0xf2, 0x00, (byte) 0xa0, (byte) 0xc9, (byte) 0x1e, (byte) 0xfb, (byte) 0x8b
38-
});
39-
38+
GUID GUID_DEVINTERFACE_DISK = new GUID("53F56307-B6BF-11D0-94F2-00A0C91EFB8B");
39+
40+
41+
/**
42+
* Drivers for serial ports register instances of this device interface
43+
* class to notify the operating system and applications of the presence of
44+
* COM ports.
45+
*/
46+
GUID GUID_DEVINTERFACE_COMPORT = new GUID("86E0D1E0-8089-11D0-9CE4-08003E301F73");
47+
4048
/**
4149
* Return only the device that is associated with the system default device interface, if one is set, for the
4250
* specified device interface classes.
4351
*/
44-
public int DIGCF_DEFAULT = 0x1;
52+
int DIGCF_DEFAULT = 0x1;
4553

4654
/**
4755
* Return only devices that are currently present in a system.
4856
*/
49-
public int DIGCF_PRESENT = 0x2;
57+
int DIGCF_PRESENT = 0x2;
5058

5159
/**
5260
* Return a list of installed devices for all device setup classes or all device interface classes.
5361
*/
54-
public int DIGCF_ALLCLASSES = 0x4;
62+
int DIGCF_ALLCLASSES = 0x4;
5563

5664
/**
5765
* Return only devices that are a part of the current hardware profile.
5866
*/
59-
public int DIGCF_PROFILE = 0x8;
67+
int DIGCF_PROFILE = 0x8;
6068

6169
/**
6270
* Return devices that support device interfaces for the specified device interface classes. This flag must be set
6371
* in the Flags parameter if the Enumerator parameter specifies a device instance ID.
6472
*/
65-
public int DIGCF_DEVICEINTERFACE = 0x10;
73+
int DIGCF_DEVICEINTERFACE = 0x10;
6674

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

7381
/**
7482
* Removable.
7583
*/
76-
public int CM_DEVCAP_REMOVABLE = 0x00000004;
84+
int CM_DEVCAP_REMOVABLE = 0x00000004;
85+
86+
87+
/** make change in all hardware profiles */
88+
int DICS_FLAG_GLOBAL = 0x00000001;
89+
/** make change in specified profile only */
90+
int DICS_FLAG_CONFIGSPECIFIC = 0x00000002;
91+
/** 1 or more hardware profile-specific changes to follow. */
92+
int DICS_FLAG_CONFIGGENERAL = 0x00000004;
93+
94+
/**
95+
* Open/Create/Delete device key.
96+
*
97+
* @see SetupDiCreateDevRegKey , SetupDiOpenDevRegKey, and
98+
* SetupDiDeleteDevRegKey.
99+
*/
100+
101+
int DIREG_DEV = 0x00000001;
102+
/**
103+
* Open/Create/Delete driver key
104+
*
105+
* @see SetupDiCreateDevRegKey, SetupDiOpenDevRegKey, and
106+
* SetupDiDeleteDevRegKey.
107+
*/
108+
109+
int DIREG_DRV = 0x00000002;
110+
/**
111+
* Delete both driver and Device key
112+
*
113+
* @see SetupDiCreateDevRegKey, SetupDiOpenDevRegKey, and
114+
* SetupDiDeleteDevRegKey.
115+
*/
116+
117+
int DIREG_BOTH = 0x00000004;
118+
119+
/**
120+
* DeviceDesc (R/W)
121+
* <p>
122+
* Device registry property codes (Codes marked as read-only (R) may only be
123+
* used for SetupDiGetDeviceRegistryProperty)
124+
* <p>
125+
* These values should cover the same set of registry properties as defined
126+
* by the CM_DRP codes in cfgmgr32.h.
127+
*/
128+
int SPDRP_DEVICEDESC = 0x00000000;
129+
77130

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

296+
/**
297+
* The SetupDiOpenDevRegKey function opens a registry key for device-specific configuration information.
298+
* <p>
299+
* Depending on the value that is passed in the samDesired parameter, it might be necessary for the caller of this
300+
* function to be a member of the Administrators group.
301+
* <p>
302+
* Close the handle returned from this function by calling RegCloseKey.
303+
* <p>
304+
* The specified device instance must be registered before this function is called. However, be aware that the
305+
* operating system automatically registers PnP device instances. For information about how to register non-PnP
306+
* device instances, see SetupDiRegisterDeviceInfo.
307+
*
308+
* @param deviceInfoSet
309+
* A handle to the device information set that contains a device information element that represents the
310+
* device for which to open a registry key.
311+
* @param deviceInfoData
312+
* A pointer to an {@link SP_DEVINFO_DATA} structure that specifies the device information element in
313+
* DeviceInfoSet.
314+
* @param scope
315+
* he scope of the registry key to open. The scope determines where the information is stored. The scope
316+
* can be global or specific to a hardware profile. The scope is specified by one of the following
317+
* values:
318+
* <ul>
319+
* <li>DICS_FLAG_GLOBAL Open a key to store global configuration information. This information is not
320+
* specific to a particular hardware profile. This opens a key that is rooted at HKEY_LOCAL_MACHINE. The
321+
* exact key opened depends on the value of the KeyType parameter. <li>DICS_FLAG_CONFIGSPECIFIC Open a
322+
* key to store hardware profile-specific configuration information. This key is rooted at one of the
323+
* hardware-profile specific branches, instead of HKEY_LOCAL_MACHINE. The exact key opened depends on the
324+
* value of the KeyType parameter.
325+
* </ul>
326+
* @param hwProfile
327+
* A hardware profile value, which is set as follows:
328+
* <ul>
329+
* <li>If Scope is set to DICS_FLAG_CONFIGSPECIFIC, HwProfile specifies the hardware profile of the key
330+
* that is to be opened. <li>If HwProfile is 0, the key for the current hardware profile is opened. <li>
331+
* If Scope is DICS_FLAG_GLOBAL, HwProfile is ignored.
332+
* </ul>
333+
* @param keyType
334+
* The type of registry storage key to open, which can be one of the following values:
335+
* <ul>
336+
* <li> {@link #DIREG_DEV} Open a hardware key for the device. <li>{@link #DIREG_DRV} Open a software key
337+
* for the device. For more information about a device's hardware and software keys, see Registry Trees
338+
* and Keys for Devices and Drivers.
339+
* </ul>
340+
* @param samDesired
341+
* The registry security access that is required for the requested key. For information about registry
342+
* security access values of type REGSAM, see the Microsoft Windows SDK documentation.
343+
* @return If the function is successful, it returns a handle to an opened registry key where private configuration
344+
* data about this device instance can be stored/retrieved.
345+
* <p>
346+
* If the function fails, it returns INVALID_HANDLE_VALUE. To get extended error information, call
347+
* GetLastError.
348+
*/
349+
HKEY SetupDiOpenDevRegKey(HANDLE deviceInfoSet, SP_DEVINFO_DATA deviceInfoData, int scope, int hwProfile, int keyType, int samDesired);
350+
351+
/**
352+
* The SetupDiEnumDeviceInfo function returns a {@link SP_DEVINFO_DATA} structure that specifies a device
353+
* information element in a device information set.
354+
* <p>
355+
* <b>Remarks</b><br>
356+
* Repeated calls to this function return a device information element for a different device. This function can be
357+
* called repeatedly to get information about all devices in the device information set.
358+
* <p>
359+
* To enumerate device information elements, an installer should initially call SetupDiEnumDeviceInfo with the
360+
* MemberIndex parameter set to 0. The installer should then increment MemberIndex and call SetupDiEnumDeviceInfo
361+
* until there are no more values (the function fails and a call to GetLastError returns ERROR_NO_MORE_ITEMS).
362+
* <p>
363+
* Call SetupDiEnumDeviceInterfaces to get a context structure for a device interface element (versus a device
364+
* information element).
365+
*
366+
*
367+
* @param deviceInfoSet
368+
* A handle to the device information set for which to return an {@link SP_DEVINFO_DATA} structure that
369+
* represents a device information element.
370+
* @param memberIndex
371+
* A zero-based index of the device information element to retrieve.
372+
* @param deviceInfoData
373+
* A pointer to an SP_DEVINFO_DATA structure to receive information about an enumerated device
374+
* information element.
375+
* @return The function returns TRUE if it is successful. Otherwise, it returns FALSE and the logged error can be
376+
* retrieved with a call to GetLastError.
377+
*/
378+
boolean SetupDiEnumDeviceInfo(HANDLE deviceInfoSet, int memberIndex, SP_DEVINFO_DATA deviceInfoData);
379+
243380
/**
244381
* An SP_DEVICE_INTERFACE_DATA structure defines a device interface in a device information set.
245382
*/
@@ -286,7 +423,7 @@ public SP_DEVICE_INTERFACE_DATA(Pointer memory) {
286423
*/
287424
public Pointer Reserved;
288425

289-
protected List getFieldOrder() {
426+
protected List<String> getFieldOrder() {
290427
return Arrays.asList(new String[] { "cbSize", "InterfaceClassGuid", "Flags", "Reserved" });
291428
}
292429
}
@@ -338,7 +475,7 @@ public SP_DEVINFO_DATA(Pointer memory) {
338475
*/
339476
public Pointer Reserved;
340477

341-
protected List getFieldOrder() {
478+
protected List<String> getFieldOrder() {
342479
return Arrays.asList(new String[] { "cbSize", "InterfaceClassGuid", "DevInst", "Reserved" });
343480
}
344481
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.sun.jna.platform.win32;
2+
3+
import static com.sun.jna.Native.getLastError;
4+
import static com.sun.jna.platform.win32.SetupApi.DICS_FLAG_GLOBAL;
5+
import static com.sun.jna.platform.win32.SetupApi.DIGCF_ALLCLASSES;
6+
import static com.sun.jna.platform.win32.SetupApi.DIGCF_DEVICEINTERFACE;
7+
import static com.sun.jna.platform.win32.SetupApi.DIGCF_PRESENT;
8+
import static com.sun.jna.platform.win32.SetupApi.DIREG_DEV;
9+
import static com.sun.jna.platform.win32.SetupApi.GUID_DEVINTERFACE_COMPORT;
10+
import static com.sun.jna.platform.win32.WinBase.INVALID_HANDLE_VALUE;
11+
import static com.sun.jna.platform.win32.WinError.ERROR_NO_MORE_ITEMS;
12+
import static com.sun.jna.platform.win32.WinNT.KEY_QUERY_VALUE;
13+
import junit.framework.TestCase;
14+
15+
import com.sun.jna.platform.win32.SetupApi.SP_DEVINFO_DATA;
16+
import com.sun.jna.platform.win32.WinNT.HANDLE;
17+
import com.sun.jna.platform.win32.WinReg.HKEY;
18+
19+
public class SetupApiTest extends TestCase {
20+
/**
21+
* member index for the first device, see {@link SetupApi#SetupDiEnumDeviceInfo(HANDLE, int, SP_DEVINFO_DATA)}
22+
*/
23+
private static final int FIRST_MEMBER = 0;
24+
25+
public static void main(String[] args) {
26+
junit.textui.TestRunner.run(SetupApiTest.class);
27+
}
28+
29+
/**
30+
* Tests the mapping of {@link SetupApi#SetupDiOpenDevRegKey(HANDLE, SP_DEVINFO_DATA, int, int, int, int)} .
31+
* <p>
32+
* The test pass if SetupDiOpenDevRegKey(..) returns a valid {@link HKEY} pointing to the first found device on the current machine.
33+
* <p>
34+
* NOTE: We only test the mapping of SetupDiOpenDevRegKey(..), not it's functionality.
35+
*/
36+
public void testSetupDiOpenDevRegKey() {
37+
// hDevInfoSet repesents a list of installed devices for all device
38+
// setup classes or all device interface classes
39+
HANDLE hDevInfoSet = SetupApi.INSTANCE.SetupDiGetClassDevs(null, null, null, DIGCF_ALLCLASSES);
40+
assertTrue(hDevInfoSet != INVALID_HANDLE_VALUE);
41+
42+
SP_DEVINFO_DATA devInfo = new SP_DEVINFO_DATA();
43+
// there must be least one device (drive,processor,pci,usb,...) on the
44+
// current machine
45+
assertTrue(SetupApi.INSTANCE.SetupDiEnumDeviceInfo(hDevInfoSet, FIRST_MEMBER, devInfo));
46+
47+
HKEY hDeviceKey = SetupApi.INSTANCE.SetupDiOpenDevRegKey(hDevInfoSet, devInfo, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
48+
assertTrue(hDeviceKey != INVALID_HANDLE_VALUE);
49+
50+
Advapi32.INSTANCE.RegCloseKey(hDeviceKey);
51+
}
52+
53+
/**
54+
* Tests the mapping of {@link SetupApi#SetupDiEnumDeviceInfo(HANDLE, int, SP_DEVINFO_DATA)} .
55+
* <p>
56+
* There are 2 different results possible, depending availability of an COM-Port on the current machine:
57+
* <ul>
58+
* <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.
59+
* <li>If the current machine has at least one COM-Port the method must succeed. The test pass if no exception is thrown.
60+
* </ul>
61+
*/
62+
public void testSetupDiEnumDeviceInfo() {
63+
HANDLE hDevInfoSet = SetupApi.INSTANCE.SetupDiGetClassDevs(GUID_DEVINTERFACE_COMPORT, null, null, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
64+
SP_DEVINFO_DATA devInfo = new SP_DEVINFO_DATA();
65+
boolean succeed = SetupApi.INSTANCE.SetupDiEnumDeviceInfo(hDevInfoSet, FIRST_MEMBER, devInfo);
66+
boolean hasNoMoreItems = (getLastError() == ERROR_NO_MORE_ITEMS);
67+
68+
assertTrue(succeed || hasNoMoreItems);
69+
}
70+
}

0 commit comments

Comments
 (0)