30
30
import com .sun .jna .Native ;
31
31
import com .sun .jna .platform .win32 .WinDef .DWORD ;
32
32
import com .sun .jna .platform .win32 .WinDef .DWORDByReference ;
33
+ import java .util .Collections ;
33
34
34
35
/**
35
36
* Pdh utility API.
@@ -113,9 +114,8 @@ public static int PdhLookupPerfIndexByEnglishName(String szNameBuffer) {
113
114
114
115
/**
115
116
* 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.
119
119
*
120
120
* @param szDataSource
121
121
* String that specifies the name of the log file used to
@@ -137,113 +137,111 @@ public static int PdhLookupPerfIndexByEnglishName(String szNameBuffer) {
137
137
* returned.
138
138
* @return Returns a List of Strings of the counters for the object.
139
139
*/
140
- public static List < String > PdhEnumObjectItemCounters (String szDataSource , String szMachineName , String szObjectName ,
140
+ public static PdhEnumObjectItems PdhEnumObjectItems (String szDataSource , String szMachineName , String szObjectName ,
141
141
int dwDetailLevel ) {
142
142
List <String > counters = new ArrayList <String >();
143
+ List <String > instances = new ArrayList <String >();
143
144
144
145
// Call once to get string lengths
145
146
DWORDByReference pcchCounterListLength = new DWORDByReference (new DWORD (0 ));
146
147
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 ,
148
149
pcchInstanceListLength , dwDetailLevel , 0 );
150
+ if (result != WinError .ERROR_SUCCESS && result != Pdh .PDH_MORE_DATA ) {
151
+ throw new Win32Exception (result );
152
+ }
149
153
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 );
153
170
}
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 );
160
171
161
172
// 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 ;
169
189
}
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 ;
173
208
}
174
- counters .add (s );
175
- // Increment for string + null terminator
176
- offset += (s .length () + 1 ) * CHAR_TO_BYTES ;
177
209
}
178
210
179
- return counters ;
211
+ return new PdhEnumObjectItems ( counters , instances ) ;
180
212
}
181
213
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 >();
211
214
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 ;
217
218
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 () {
220
229
return instances ;
221
230
}
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 ();
235
235
} else {
236
- s = mszInstanceList .getWideString (offset );
237
- }
238
- // list ends with double null
239
- if (s .isEmpty ()) {
240
- break ;
236
+ return inputList ;
241
237
}
242
- instances .add (s );
243
- // Increment for string + null terminator
244
- offset += (s .length () + 1 ) * CHAR_TO_BYTES ;
245
238
}
246
239
247
- return instances ;
240
+ @ Override
241
+ public String toString () {
242
+ return "PdhEnumObjectItems{" + "counters=" + counters + ", instances=" + instances + '}' ;
243
+ }
244
+
245
+
248
246
}
249
247
}
0 commit comments