3030import com .sun .jna .Native ;
3131import com .sun .jna .platform .win32 .WinDef .DWORD ;
3232import 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}
0 commit comments