Skip to content

Commit 14b746f

Browse files
Fix PdhTest + update PdhEnumObjectItems
1 parent e0a28a3 commit 14b746f

File tree

3 files changed

+96
-96
lines changed

3 files changed

+96
-96
lines changed

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

+6-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
*/
2424
package com.sun.jna.platform.win32;
2525

26-
import java.util.List;
27-
2826
import com.sun.jna.Native;
2927
import com.sun.jna.Pointer;
3028
import com.sun.jna.Structure;
@@ -55,6 +53,12 @@ public interface Pdh extends StdCallLibrary {
5553
/** Maximum full counter log name length. */
5654
int PDH_MAX_DATASOURCE_PATH = 1024;
5755

56+
int PDH_MORE_DATA = 0x800007D2;
57+
int PDH_INVALID_ARGUMENT = 0xC0000BBD;
58+
int PDH_MEMORY_ALLOCATION_FAILURE = 0xC0000BBB;
59+
int PDH_CSTATUS_NO_MACHINE = 0x800007D0;
60+
int PDH_CSTATUS_NO_OBJECT = 0xC0000BB8;
61+
5862
/* TODO
5963
* LPVOID CALLBACK AllocateMemory(_In_ SIZE_T AllocSize,_In_ LPVOID pContext)
6064
* void CALLBACK FreeMemory(LPVOID pBuffer,LPVOID pContext)

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

+84-86
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import com.sun.jna.Native;
3131
import com.sun.jna.platform.win32.WinDef.DWORD;
3232
import com.sun.jna.platform.win32.WinDef.DWORDByReference;
33+
import java.util.Collections;
3334

3435
/**
3536
* Pdh utility API.
@@ -113,9 +114,8 @@ public static int PdhLookupPerfIndexByEnglishName(String szNameBuffer) {
113114

114115
/**
115116
* Utility method to call Pdh's PdhEnumObjectItems that allocates the
116-
* required memory for the mszCounterList parameter based on the type
117-
* mapping used, calls to PdhEnumObjectItems, and returns the received lists
118-
* of strings.
117+
* required memory for the lists parameters based on the type mapping used,
118+
* calls to PdhEnumObjectItems, and returns the received lists of strings.
119119
*
120120
* @param szDataSource
121121
* String that specifies the name of the log file used to
@@ -137,113 +137,111 @@ public static int PdhLookupPerfIndexByEnglishName(String szNameBuffer) {
137137
* returned.
138138
* @return Returns a List of Strings of the counters for the object.
139139
*/
140-
public static List<String> PdhEnumObjectItemCounters(String szDataSource, String szMachineName, String szObjectName,
140+
public static PdhEnumObjectItems PdhEnumObjectItems(String szDataSource, String szMachineName, String szObjectName,
141141
int dwDetailLevel) {
142142
List<String> counters = new ArrayList<String>();
143+
List<String> instances = new ArrayList<String>();
143144

144145
// Call once to get string lengths
145146
DWORDByReference pcchCounterListLength = new DWORDByReference(new DWORD(0));
146147
DWORDByReference pcchInstanceListLength = new DWORDByReference(new DWORD(0));
147-
Pdh.INSTANCE.PdhEnumObjectItems(szDataSource, szMachineName, szObjectName, null, pcchCounterListLength, null,
148+
int result = Pdh.INSTANCE.PdhEnumObjectItems(szDataSource, szMachineName, szObjectName, null, pcchCounterListLength, null,
148149
pcchInstanceListLength, dwDetailLevel, 0);
150+
if(result != WinError.ERROR_SUCCESS && result != Pdh.PDH_MORE_DATA) {
151+
throw new Win32Exception(result);
152+
}
149153

150-
// Can't allocate 0 memory if no counters
151-
if (pcchCounterListLength.getValue().intValue() < 1) {
152-
return counters;
154+
Memory mszCounterList = null;
155+
Memory mszInstanceList = null;
156+
157+
if (pcchCounterListLength.getValue().intValue() > 0) {
158+
mszCounterList = new Memory(pcchCounterListLength.getValue().intValue() * CHAR_TO_BYTES);
159+
}
160+
161+
if (pcchInstanceListLength.getValue().intValue() > 0) {
162+
mszInstanceList = new Memory(pcchInstanceListLength.getValue().intValue() * CHAR_TO_BYTES);
163+
}
164+
165+
result = Pdh.INSTANCE.PdhEnumObjectItems(szDataSource, szMachineName, szObjectName, mszCounterList,
166+
pcchCounterListLength, mszInstanceList, pcchInstanceListLength, dwDetailLevel, 0);
167+
168+
if(result != WinError.ERROR_SUCCESS) {
169+
throw new Win32Exception(result);
153170
}
154-
// Allocate memory and call again to populate strings
155-
Memory mszCounterList = new Memory(pcchCounterListLength.getValue().intValue() * CHAR_TO_BYTES);
156-
// Don't need the instances
157-
pcchInstanceListLength.getValue().setValue(0);
158-
Pdh.INSTANCE.PdhEnumObjectItems(szDataSource, szMachineName, szObjectName, mszCounterList,
159-
pcchCounterListLength, null, pcchInstanceListLength, dwDetailLevel, 0);
160171

161172
// Fetch counters
162-
int offset = 0;
163-
while (offset < mszCounterList.size()) {
164-
String s = null;
165-
if (CHAR_TO_BYTES == 1) {
166-
s = mszCounterList.getString(offset);
167-
} else {
168-
s = mszCounterList.getWideString(offset);
173+
if (mszCounterList != null) {
174+
int offset = 0;
175+
while (offset < mszCounterList.size()) {
176+
String s = null;
177+
if (CHAR_TO_BYTES == 1) {
178+
s = mszCounterList.getString(offset);
179+
} else {
180+
s = mszCounterList.getWideString(offset);
181+
}
182+
// list ends with double null
183+
if (s.isEmpty()) {
184+
break;
185+
}
186+
counters.add(s);
187+
// Increment for string + null terminator
188+
offset += (s.length() + 1) * CHAR_TO_BYTES;
169189
}
170-
// list ends with double null
171-
if (s.isEmpty()) {
172-
break;
190+
}
191+
192+
if(mszInstanceList != null) {
193+
int offset = 0;
194+
while (offset < mszInstanceList.size()) {
195+
String s = null;
196+
if (CHAR_TO_BYTES == 1) {
197+
s = mszInstanceList.getString(offset);
198+
} else {
199+
s = mszInstanceList.getWideString(offset);
200+
}
201+
// list ends with double null
202+
if (s.isEmpty()) {
203+
break;
204+
}
205+
instances.add(s);
206+
// Increment for string + null terminator
207+
offset += (s.length() + 1) * CHAR_TO_BYTES;
173208
}
174-
counters.add(s);
175-
// Increment for string + null terminator
176-
offset += (s.length() + 1) * CHAR_TO_BYTES;
177209
}
178210

179-
return counters;
211+
return new PdhEnumObjectItems(counters, instances);
180212
}
181213

182-
/**
183-
* Utility method to call Pdh's PdhEnumObjectItems that allocates the
184-
* required memory for the mszInstanceList parameters based on the type
185-
* mapping used, calls to PdhEnumObjectItems, and returns the received lists
186-
* of strings.
187-
*
188-
* @param szDataSource
189-
* String that specifies the name of the log file used to
190-
* enumerate the counter and instance names. If NULL, the
191-
* function uses the computer specified in the szMachineName
192-
* parameter to enumerate the names.
193-
* @param szMachineName
194-
* String that specifies the name of the computer that contains
195-
* the counter and instance names that you want to enumerate.
196-
* Include the leading slashes in the computer name, for example,
197-
* \\computername. If the szDataSource parameter is NULL, you can
198-
* set szMachineName to NULL to specify the local computer.
199-
* @param szObjectName
200-
* String that specifies the name of the object whose counter and
201-
* instance names you want to enumerate.
202-
* @param dwDetailLevel
203-
* Detail level of the performance items to return. All items
204-
* that are of the specified detail level or less will be
205-
* returned.
206-
* @return Returns a Lists of Strings of the instances of the object.
207-
*/
208-
public static List<String> PdhEnumObjectItemInstances(String szDataSource, String szMachineName,
209-
String szObjectName, int dwDetailLevel) {
210-
List<String> instances = new ArrayList<String>();
211214

212-
// Call once to get string lengths
213-
DWORDByReference pcchCounterListLength = new DWORDByReference(new DWORD(0));
214-
DWORDByReference pcchInstanceListLength = new DWORDByReference(new DWORD(0));
215-
Pdh.INSTANCE.PdhEnumObjectItems(szDataSource, szMachineName, szObjectName, null, pcchCounterListLength, null,
216-
pcchInstanceListLength, dwDetailLevel, 0);
215+
public static class PdhEnumObjectItems {
216+
private final List<String> counters;
217+
private final List<String> instances;
217218

218-
// Can't allocate 0 memory if no instances
219-
if (pcchInstanceListLength.getValue().intValue() < 1) {
219+
public PdhEnumObjectItems(List<String> counters, List<String> instances) {
220+
this.counters = Collections.unmodifiableList(emptyListForNullList(counters));
221+
this.instances = Collections.unmodifiableList(emptyListForNullList(instances));
222+
}
223+
224+
public List<String> getCounters() {
225+
return counters;
226+
}
227+
228+
public List<String> getInstances() {
220229
return instances;
221230
}
222-
// Allocate memory and call again to populate strings
223-
Memory mszInstanceList = new Memory(pcchInstanceListLength.getValue().intValue() * CHAR_TO_BYTES);
224-
// Don't need the counters
225-
pcchCounterListLength.getValue().setValue(0);
226-
Pdh.INSTANCE.PdhEnumObjectItems(szDataSource, szMachineName, szObjectName, null, pcchCounterListLength,
227-
mszInstanceList, pcchInstanceListLength, dwDetailLevel, 0);
228-
229-
// Fetch instances
230-
int offset = 0;
231-
while (offset < mszInstanceList.size()) {
232-
String s = null;
233-
if (CHAR_TO_BYTES == 1) {
234-
s = mszInstanceList.getString(offset);
231+
232+
private List<String> emptyListForNullList (List<String> inputList) {
233+
if(inputList == null) {
234+
return Collections.<String>emptyList();
235235
} else {
236-
s = mszInstanceList.getWideString(offset);
237-
}
238-
// list ends with double null
239-
if (s.isEmpty()) {
240-
break;
236+
return inputList;
241237
}
242-
instances.add(s);
243-
// Increment for string + null terminator
244-
offset += (s.length() + 1) * CHAR_TO_BYTES;
245238
}
246239

247-
return instances;
240+
@Override
241+
public String toString() {
242+
return "PdhEnumObjectItems{" + "counters=" + counters + ", instances=" + instances + '}';
243+
}
244+
245+
248246
}
249247
}

contrib/platform/test/com/sun/jna/platform/win32/PdhTest.java

+6-8
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@
1616
import java.util.Collection;
1717
import java.util.HashMap;
1818
import java.util.LinkedList;
19-
import java.util.List;
2019
import java.util.Map;
2120

2221
import org.junit.Test;
2322

2423
import com.sun.jna.Native;
2524
import com.sun.jna.platform.win32.Pdh.PDH_COUNTER_PATH_ELEMENTS;
2625
import com.sun.jna.platform.win32.Pdh.PDH_RAW_COUNTER;
26+
import com.sun.jna.platform.win32.PdhUtil.PdhEnumObjectItems;
2727
import com.sun.jna.platform.win32.WinDef.DWORD;
2828
import com.sun.jna.platform.win32.WinDef.DWORDByReference;
2929
import com.sun.jna.platform.win32.WinNT.HANDLE;
@@ -182,19 +182,17 @@ public void testLookupPerfIndex() {
182182
@Test
183183
public void testEnumObjectItems() {
184184
if (AbstractWin32TestSupport.isEnglishLocale) {
185-
String processorStr = "Processor";
185+
String processorStr = "Processor";
186186
String processorTimeStr = "% Processor Time";
187187

188188
// Fetch the counter and instance names
189-
List<String> instances = PdhUtil.PdhEnumObjectItemInstances(null, null, processorStr, 100);
189+
PdhEnumObjectItems objects = PdhUtil.PdhEnumObjectItems(null, null, processorStr, 100);
190190

191-
// Should have at least one processor and total instance
192-
assertTrue(instances.contains("0"));
193-
assertTrue(instances.contains("_Total"));
191+
assertTrue(objects.getInstances().contains("0"));
192+
assertTrue(objects.getInstances().contains("_Total"));
194193

195194
// Should have a "% Processor Time" counter
196-
List<String> counters = PdhUtil.PdhEnumObjectItemCounters(null, null, processorStr, 100);
197-
assertTrue(counters.contains(processorTimeStr));
195+
assertTrue(objects.getCounters().contains(processorTimeStr));
198196
} else {
199197
System.err.println("testEnumObjectItems test can only be run with english locale.");
200198
}

0 commit comments

Comments
 (0)