org.rzo.yajsw.os.ms.win.w32.Pdh.java Source code

Java tutorial

Introduction

Here is the source code for org.rzo.yajsw.os.ms.win.w32.Pdh.java

Source

/* This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * <p/>
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.  
 */
package org.rzo.yajsw.os.ms.win.w32;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import jnacontrib.jna.Options;

import org.apache.commons.collections.Bag;
import org.apache.commons.collections.bag.HashBag;
import org.rzo.yajsw.os.OperatingSystem;
import org.rzo.yajsw.util.File;

import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.Union;
import com.sun.jna.WString;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
import com.sun.jna.win32.StdCallLibrary;

// TODO: Auto-generated Javadoc
/**
 * The Class Pdh.
 */
public class Pdh {

    /**
     * The Interface Pdhdll.
     */
    interface Pdhdll extends StdCallLibrary {

        /** The INSTANCE. */
        Pdhdll INSTANCE = (Pdhdll) Native.loadLibrary("C:/WINDOWS/system32/pdh.dll", Pdhdll.class);

        /*
         * PDH_STATUS PdhOpenQuery( __in LPCTSTR szDataSource, __in DWORD_PTR
         * dwUserData, __out PDH_HQUERY phQuery );
         */
        /**
         * Pdh open query.
         * 
         * @param szDataSource
         *            the sz data source
         * @param dwUserData
         *            the dw user data
         * @param phQuery
         *            the ph query
         * 
         * @return the int
         */
        int PdhOpenQuery(Pointer szDataSource, Pointer dwUserData, PointerByReference phQuery);

        /*
         * PDH_STATUS PdhValidatePath( __in LPCTSTR szFullCounterPath );
         */
        /**
         * Pdh validate path a.
         * 
         * @param szFullCounterPath
         *            the sz full counter path
         * 
         * @return the int
         */
        int PdhValidatePathA(String szFullCounterPath);

        /*
         * PDH_STATUS PdhCollectQueryData( __in_out PDH_HQUERY hQuery );
         */
        /**
         * Pdh collect query data.
         * 
         * @param hQuery
         *            the h query
         * 
         * @return the int
         */
        int PdhCollectQueryData(Pointer hQuery);

        /*
         * PDH_STATUS PdhGetFormattedCounterValue( __in PDH_HCOUNTER hCounter,
         * __in DWORD dwFormat, __out LPDWORD lpdwType, __out
         * PPDH_FMT_COUNTERVALUE pValue );
         */
        /**
         * Pdh get formatted counter value.
         * 
         * @param hCounter
         *            the h counter
         * @param dwFormat
         *            the dw format
         * @param lpdwType
         *            the lpdw type
         * @param pValue
         *            the value
         * 
         * @return the int
         */
        int PdhGetFormattedCounterValue(Pointer hCounter, int dwFormat, IntByReference lpdwType, Pointer pValue);

        /*
         * typedef struct _PDH_FMT_COUNTERVALUE { DWORD CStatus; union { LONG
         * longValue; double doubleValue; LONGLONG largeValue; LPCSTR
         * AnsiStringValue; LPCWSTR WideStringValue; }; } PDH_FMT_COUNTERVALUE,
         * PPDH_FMT_COUNTERVALUE;
         */

        /*
         * PDH_STATUS PdhAddCounter( __in PDH_HQUERY hQuery, __in LPCTSTR
         * szFullCounterPath, __in DWORD_PTR dwUserData, __out PDH_HCOUNTER
         * phCounter );
         */
        /**
         * Pdh add counter a.
         * 
         * @param hQuery
         *            the h query
         * @param szFullCounterPath
         *            the sz full counter path
         * @param dwUserData
         *            the dw user data
         * @param phCounter
         *            the ph counter
         * 
         * @return the int
         */
        int PdhAddCounterA(Pointer hQuery, String szFullCounterPath, int dwUserData, PointerByReference phCounter);

        /*
         * PDH_STATUS PdhAddEnglishCounter( __in PDH_HQUERY hQuery, __in LPCTSTR
         * szFullCounterPath, __in DWORD_PTR dwUserData, __out PDH_HCOUNTER
         * phCounter );
         */
        /**
         * Pdh add009 counter a.
         * 
         * @param hQuery
         *            the h query
         * @param szFullCounterPath
         *            the sz full counter path
         * @param dwUserData
         *            the dw user data
         * @param phCounter
         *            the ph counter
         * 
         * @return the int
         */
        int PdhAdd009CounterA(Pointer hQuery, String szFullCounterPath, int dwUserData,
                PointerByReference phCounter);

        /** The ERRO r_ success. */
        int ERROR_SUCCESS = 0;

        /** The PD h_ fm t_ double. */
        int PDH_FMT_DOUBLE = 0x00000200;

        /** The PD h_ fm t_ long. */
        int PDH_FMT_LONG = 0x00000100;

        /*
         * PDH_STATUS PdhRemoveCounter( __in PDH_HCOUNTER hCounter );
         */
        /**
         * Pdh remove counter.
         * 
         * @param hCounter
         *            the h counter
         * 
         * @return the int
         */
        int PdhRemoveCounter(Pointer hCounter);

        /*
         * PDH_STATUS PdhCloseQuery( __in PDH_HQUERY hQuery );
         */
        /**
         * Pdh close query.
         * 
         * @param hQuery
         *            the h query
         * 
         * @return the int
         */
        int PdhCloseQuery(Pointer hQuery);

        /*
         * PDH_STATUS PdhEnumObjectItems( __in LPCTSTR szDataSource, __in
         * LPCTSTR szMachineName, __in LPCTSTR szObjectName, __out LPTSTR
         * mszCounterList, __in_out LPDWORD pcchCounterListLength, __out LPTSTR
         * mszInstanceList, __in_out LPDWORD pcchInstanceListLength, __in DWORD
         * dwDetailLevel, DWORD dwFlags );
         */
        /**
         * Pdh enum object items a.
         * 
         * @param szDataSource
         *            the sz data source
         * @param szMachineName
         *            the sz machine name
         * @param szObjectName
         *            the sz object name
         * @param mszCounterList
         *            the msz counter list
         * @param pcchCounterListLength
         *            the pcch counter list length
         * @param mszInstanceList
         *            the msz instance list
         * @param pcchInstanceListLength
         *            the pcch instance list length
         * @param dwDetailLevel
         *            the dw detail level
         * @param dwFlags
         *            the dw flags
         * 
         * @return the int
         */
        int PdhEnumObjectItemsA(String szDataSource, String szMachineName, String szObjectName,
                Memory mszCounterList, IntByReference pcchCounterListLength, Memory mszInstanceList,
                IntByReference pcchInstanceListLength, int dwDetailLevel, int dwFlags);

        /** The PER f_ detai l_ wizard. */
        int PERF_DETAIL_WIZARD = 400;

        /** The PD h_ mor e_ data. */
        int PDH_MORE_DATA = 0x800007D2;

        /*
         * DH_STATUS PdhLookupPerfNameByIndex( __in LPCTSTR szMachineName, __in
         * DWORD dwNameIndex, __out LPTSTR szNameBuffer, __in LPDWORD
         * pcchNameBufferSize );
         */
        /**
         * Pdh lookup perf name by index a.
         * 
         * @param szMachineName
         *            the sz machine name
         * @param dwNameIndex
         *            the dw name index
         * @param szNameBuffer
         *            the sz name buffer
         * @param pcchNameBufferSize
         *            the pcch name buffer size
         * 
         * @return the int
         */
        int PdhLookupPerfNameByIndexA(String szMachineName, int dwNameIndex, Memory szNameBuffer,
                IntByReference pcchNameBufferSize);

        /*
         * PDH_STATUS PdhParseCounterPath( __in LPCTSTR szFullPathBuffer, __out
         * PDH_COUNTER_PATH_ELEMENTS pCounterPathElements, __in_out LPDWORD
         * pdwBufferSize, DWORD dwFlags );
         */
        /**
         * Pdh parse counter path a.
         * 
         * @param szFullPathBuffer
         *            the sz full path buffer
         * @param pCounterPathElements
         *            the counter path elements
         * @param pdwBufferSize
         *            the pdw buffer size
         * @param dwFlags
         *            the dw flags
         * 
         * @return the int
         */
        int PdhParseCounterPathA(String szFullPathBuffer, Pointer pCounterPathElements,
                IntByReference pdwBufferSize, int dwFlags);

    }// Pdhdll

    /**
     * The Interface Advapi32.
     */
    interface Advapi32 extends StdCallLibrary {

        /** The INSTANCE. */
        Advapi32 INSTANCE = (Advapi32) Native.loadLibrary("Advapi32", Advapi32.class);//, Options.UNICODE_OPTIONS);

        /*
         * LONG WINAPI RegOpenKeyEx( HKEY hKey, LPCTSTR lpSubKey, DWORD
         * ulOptions, REGSAM samDesired, PHKEY phkResult );
         */
        /**
         * Reg open key ex a.
         * 
         * @param hKey
         *            the h key
         * @param lpSubKey
         *            the lp sub key
         * @param ulOptions
         *            the ul options
         * @param samDesired
         *            the sam desired
         * @param phkResult
         *            the phk result
         * 
         * @return the int
         */
        int RegOpenKeyExA(int hKey, String lpSubKey, int ulOptions, int samDesired, IntByReference phkResult);

        /** The HKE y_ loca l_ machine. */
        int HKEY_LOCAL_MACHINE = 0x80000002;

        /** The KE y_ read. */
        int KEY_READ = 0x20019;

        /*
         * LONG WINAPI RegCloseKey( HKEY hKey );
         */
        /**
         * Reg close key.
         * 
         * @param hKey
         *            the h key
         * 
         * @return the int
         */
        public int RegCloseKey(int hKey);

        /*
         * LONG WINAPI RegQueryValueEx( __in HKEY hKey, __in LPCTSTR
         * lpValueName, LPDWORD lpReserved, __out LPDWORD lpType, __out LPBYTE
         * lpData, __in_out LPDWORD lpcbData );
         */
        /**
         * Reg query value ex a.
         * 
         * @param hKey
         *            the h key
         * @param lpValueName
         *            the lp value name
         * @param lpReserved
         *            the lp reserved
         * @param lpType
         *            the lp type
         * @param lpData
         *            the lp data
         * @param lpcbData
         *            the lpcb data
         * 
         * @return the int
         */
        int RegQueryValueExA(int hKey, String lpValueName, Pointer lpReserved, IntByReference lpType,
                Pointer lpData, IntByReference lpcbData);

        /** The HKE y_ performanc e_ data. */
        int HKEY_PERFORMANCE_DATA = 0x80000004;

        /** The ERRO r_ mor e_ data. */
        int ERROR_MORE_DATA = 234;

    }

    /**
     * The Class PDH_FMT_COUNTERVALUE.
     */
    public static class PDH_FMT_COUNTERVALUE extends Structure {

        /** The C status. */
        public int CStatus;

        /** The Value. */
        public ValueUnion Value;
    }

    /**
     * The Class ValueUnion.
     */
    public static class ValueUnion extends Union {

        /** The long value. */
        public int longValue;

        /** The double value. */
        public double doubleValue;

        /** The large value. */
        public long largeValue;

        /** The Ansi string value. */
        public String AnsiStringValue;

        /** The Wide string value. */
        public WString WideStringValue;
    }

    /**
     * The Class COUNTER_PATH_ELEMENTS.
     */
    public static class COUNTER_PATH_ELEMENTS {

        /** The sz machine name. */
        public String szMachineName;

        /** The sz object name. */
        public String szObjectName;

        /** The sz instance name. */
        public String szInstanceName;

        /** The dw instance index. */
        public int dwInstanceIndex;

        /** The sz counter name. */
        public String szCounterName;

    }

    /** The MA x_ counte r_ path. */
    static int MAX_COUNTER_PATH = 256; // Maximum counter path length

    /** The PD h_ ma x_ counte r_ name. */
    static int PDH_MAX_COUNTER_NAME = 1024; // Maximum counter name length.

    /** The PD h_ ma x_ instanc e_ name. */
    static int PDH_MAX_INSTANCE_NAME = 1024; // Maximum counter instance name
    // length.
    /** The PD h_ ma x_ counte r_ path. */
    static int PDH_MAX_COUNTER_PATH = 2048; // Maximum full counter path

    // length.

    /**
     * The Class HddCounter.
     */
    static public class HddCounter implements PdhCounter {

        /** The _file. */
        private File _file;

        /** The _free space percent. */
        private boolean _freeSpacePercent = false;

        /** The _free space. */
        private boolean _freeSpace = false;

        /** The _used space. */
        private boolean _usedSpace = false;

        /** The _total space. */
        private boolean _totalSpace = false;

        /**
         * Instantiates a new hdd counter.
         * 
         * @param counter
         *            the counter
         */
        public HddCounter(String counter) {

            String hdd = counter.substring(counter.indexOf('(') + 1, counter.indexOf(')'));
            String counterHdd = new File(hdd).getPath();
            /*
             * int i=0; do { counterHdd = getHddFileName(hdd); if (counterHdd ==
             * null) try { Thread.sleep(100); } catch (InterruptedException e) {
             * // TODO Auto-generated catch block e.printStackTrace(); } i++; }
             * while (i<5 && counterHdd == null);
             */

            _file = new File(counterHdd);

            if (_file == null || !_file.exists())
                System.out.println("could not open file " + counterHdd + " " + hdd);

            if (counter.endsWith("\\% free space"))
                _freeSpacePercent = true;
            else if (counter.endsWith("\\free space"))
                _freeSpace = true;
            else if (counter.endsWith("\\used space"))
                _usedSpace = true;
            else if (counter.endsWith("\\total space"))
                _totalSpace = true;
        }

        /**
         * Gets the hdd file name.
         * 
         * @param hdd
         *            the hdd
         * 
         * @return the hdd file name
         */
        private String getHddFileName(String hdd) {
            List hdds = enumObjectItems("PhysicalDisk", true);
            String counterHdd = null;
            for (Iterator it = hdds.iterator(); it.hasNext();) {
                String s = (String) it.next();
                if (s.contains(hdd)) {
                    counterHdd = s.substring(2);
                    break;
                }
            }
            return counterHdd;
        }

        /*
         * (non-Javadoc)
         * 
         * @see org.rzo.yajsw.os.ms.win.xp.PdhCounter#close()
         */
        public void close() {
            _file = null;
        }

        /*
         * (non-Javadoc)
         * 
         * @see org.rzo.yajsw.os.ms.win.xp.PdhCounter#getDoubleValue()
         */
        public double getDoubleValue() {
            if (!isValid())
                return -1;
            if (_freeSpacePercent)
                return ((double) _file.getFreeSpace() / (double) _file.getTotalSpace()) * 100;
            if (_freeSpace)
                return _file.getFreeSpace();
            if (_usedSpace)
                return _file.getTotalSpace() - _file.getFreeSpace();
            if (_totalSpace)
                return _file.getTotalSpace();
            return -1;
        }

        /*
         * (non-Javadoc)
         * 
         * @see org.rzo.yajsw.os.ms.win.xp.PdhCounter#getIntValue()
         */
        public int getIntValue() {
            return (int) getDoubleValue();
        }

        /*
         * (non-Javadoc)
         * 
         * @see org.rzo.yajsw.os.ms.win.xp.PdhCounter#isValid()
         */
        public boolean isValid() {
            return _file != null && _file.exists();
        }

    }

    /**
     * The Class Counter.
     */
    static public class Counter implements PdhCounter {

        /** The _h query. */
        PointerByReference _hQuery = new PointerByReference();

        /** The _h counter. */
        PointerByReference _hCounter = new PointerByReference();

        /** The _counter. */
        String _counter;

        /**
         * Instantiates a new counter.
         * 
         * @param counter
         *            the counter
         * @param english
         *            the english
         */
        Counter(String counter, boolean english) {
            int ret = Pdhdll.INSTANCE.PdhOpenQuery(null, null, _hQuery);
            _counter = counter;
            if (ret != Pdhdll.ERROR_SUCCESS)
                System.out.println("PdhOpenQuery " + Integer.toHexString(ret));

            if (english)
                ret = Pdhdll.INSTANCE.PdhAdd009CounterA(_hQuery.getValue(), counter, 0, _hCounter);
            else
                ret = Pdhdll.INSTANCE.PdhAddCounterA(_hQuery.getValue(), counter, 0, _hCounter);
            if (ret != Pdhdll.ERROR_SUCCESS)
                System.out.println(Integer.toHexString(ret));
            // System.out.println("created counter: "+ _counter + " "+
            // _hQuery.getPointer() + " " +_hCounter.getPointer()+ " "+
            // _hQuery.getValue() + " " +_hCounter.getValue());
            getIntValue();
        }

        /*
         * (non-Javadoc)
         * 
         * @see org.rzo.yajsw.os.ms.win.xp.PdhCounter#isValid()
         */
        public boolean isValid() {
            return !(_hCounter == null || _hQuery == null || _hQuery.getValue().equals(null)
                    || _hCounter.getValue().equals(null));
        }

        /*
         * (non-Javadoc)
         * 
         * @see org.rzo.yajsw.os.ms.win.xp.PdhCounter#getDoubleValue()
         */
        public double getDoubleValue() {
            if (!isValid())
                return -1;
            PDH_FMT_COUNTERVALUE pdhCounterValue = new PDH_FMT_COUNTERVALUE();
            pdhCounterValue.size();
            int ret = Pdhdll.INSTANCE.PdhCollectQueryData(_hQuery.getValue());
            if (ret != Pdhdll.ERROR_SUCCESS)
                System.out.println(Integer.toHexString(ret));
            PointerByReference result = new PointerByReference();
            ret = Pdhdll.INSTANCE.PdhGetFormattedCounterValue(_hCounter.getValue(), Pdhdll.PDH_FMT_DOUBLE, null,
                    pdhCounterValue.getPointer());
            if (ret != Pdhdll.ERROR_SUCCESS)
                System.out.println(Integer.toHexString(ret));
            else {
                pdhCounterValue.read();
                return pdhCounterValue.Value.doubleValue;
            }
            return -1;
        }

        /*
         * (non-Javadoc)
         * 
         * @see org.rzo.yajsw.os.ms.win.xp.PdhCounter#getIntValue()
         */
        public int getIntValue() {
            if (!isValid())
                return -1;
            PDH_FMT_COUNTERVALUE pdhCounterValue = new PDH_FMT_COUNTERVALUE();
            pdhCounterValue.size();
            int ret = Pdhdll.INSTANCE.PdhCollectQueryData(_hQuery.getValue());
            if (ret != Pdhdll.ERROR_SUCCESS)
                System.out.println(Integer.toHexString(ret));
            PointerByReference result = new PointerByReference();
            ret = Pdhdll.INSTANCE.PdhGetFormattedCounterValue(_hCounter.getValue(), Pdhdll.PDH_FMT_LONG, null,
                    pdhCounterValue.getPointer());
            if (ret != Pdhdll.ERROR_SUCCESS)
                System.out.println(Integer.toHexString(ret));
            else {
                pdhCounterValue.read();
                return pdhCounterValue.Value.longValue;
            }
            return -1;
        }

        // call close to free sources. this is not done in finalize, because the
        // pointers may have already been finalized
        /*
         * (non-Javadoc)
         * 
         * @see org.rzo.yajsw.os.ms.win.xp.PdhCounter#close()
         */
        public void close() {
            // System.out.println("closing counter: "+_counter + " " +
            // _hCounter.getValue() + " " + _hQuery.getValue());
            if (!isValid())
                return;
            if (_hCounter != null)
                Pdhdll.INSTANCE.PdhRemoveCounter(_hCounter.getValue());

            if (_hQuery != null)
                Pdhdll.INSTANCE.PdhCloseQuery(_hQuery.getValue());

            _hQuery = null;
            _hCounter = null;
        }

    } // Counter

    /**
     * Enum object items.
     * 
     * @param objectName
     *            the object name
     * @param english
     *            the english
     * 
     * @return the list
     */
    public static List enumObjectItems(String objectName, boolean english) {
        if (english)
            objectName = translate(objectName);
        Bag bag = new HashBag();
        int pdhStatus = Pdhdll.ERROR_SUCCESS;
        Memory szCounterListBuffer = null;
        IntByReference dwCounterListSize = new IntByReference();
        Memory szInstanceListBuffer = null;
        IntByReference dwInstanceListSize = new IntByReference();
        String szThisInstance = null;

        // Determine the required buffer size for the data.
        pdhStatus = Pdhdll.INSTANCE.PdhEnumObjectItemsA(null, // real time
                // source
                null, // local machine
                objectName, // object to enumerate
                szCounterListBuffer, // pass NULL and 0
                dwCounterListSize, // to get length required
                szInstanceListBuffer, // buffer size
                dwInstanceListSize, // 
                Pdhdll.PERF_DETAIL_WIZARD, // counter detail level
                0);

        if (pdhStatus == Pdhdll.PDH_MORE_DATA) {
            // Allocate the buffers and try the call again.
            szCounterListBuffer = new Memory(dwCounterListSize.getValue() * 4);
            szInstanceListBuffer = new Memory((dwInstanceListSize.getValue() * 4));

            if ((szCounterListBuffer != null) && (szInstanceListBuffer != null)) {
                pdhStatus = Pdhdll.INSTANCE.PdhEnumObjectItemsA(null, // real
                        // time
                        // source
                        null, // local machine
                        objectName, // object to enumerate
                        szCounterListBuffer, // buffer to receive counter
                        // list
                        dwCounterListSize, szInstanceListBuffer, // buffer to
                        // receive
                        // instance
                        // list
                        dwInstanceListSize, Pdhdll.PERF_DETAIL_WIZARD, // counter
                        // detail
                        // level
                        0);

                if (pdhStatus == Pdhdll.ERROR_SUCCESS) {
                    // System.out.println ("Enumerating Processes:");

                    // Walk the instance list. The list can contain one
                    // or more null-terminated strings. The last string
                    // is followed by a second null-terminator.
                    int i = 0;
                    for (szThisInstance = szInstanceListBuffer.getString(0); szThisInstance != null
                            && szThisInstance.length() > 0; i += szThisInstance.length()
                                    + 1, szThisInstance = szInstanceListBuffer.getString(i)) {
                        // System.out.println( szThisInstance);
                        bag.add(szThisInstance);

                    }
                } else {
                    System.out.println("PdhEnumObjectItems failed with " + Integer.toHexString(pdhStatus));
                }
            } else {
                System.out.println("Unable to allocate buffers");
                // pdhStatus = ERROR_OUTOFMEMORY;
            }

        } else {
            System.out.println("PdhEnumObjectItems failed with " + Integer.toHexString(pdhStatus));
        }

        List result = new ArrayList();
        for (Iterator it = bag.uniqueSet().iterator(); it.hasNext();) {
            String str = (String) it.next();
            result.add(str);
            // System.out.println(str);
            for (int i = 1; i < bag.getCount(str); i++) {
                result.add(str + "#" + i);
                // System.out.println(str+"#"+i);
            }
        }

        return result;
    }

    /** The _indexes. */
    static Map _indexes = null;

    /**
     * Read index map.
     */
    static void readIndexMap() {
        if (_indexes != null)
            return;
        _indexes = new HashMap();
        int ret = 0;
        IntByReference hkey = new IntByReference();

        ret = Advapi32.INSTANCE.RegOpenKeyExA(Advapi32.HKEY_LOCAL_MACHINE,
                "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\009", 0, Advapi32.KEY_READ, hkey);
        // System.out.println(">> "+ret + " " +
        // Integer.toHexString(hkey.getValue()));

        int BufferSize = 1;
        int BYTEINCREMENT = 1024;
        Memory PerfData = new Memory(BufferSize);
        PerfData.clear();
        IntByReference PBufferSize = new IntByReference();

        PBufferSize.setValue(BufferSize);

        // System.out.println("Allocating memory...");
        for (ret = Advapi32.INSTANCE.RegQueryValueExA(hkey.getValue(), "Counter", null, null, PerfData,
                PBufferSize); ret == Advapi32.ERROR_MORE_DATA; ret = Advapi32.INSTANCE
                        .RegQueryValueExA(hkey.getValue(), "Counter", null, null, PerfData, PBufferSize)) {

            // Get a buffer that is big enough.

            BufferSize += BYTEINCREMENT;
            PBufferSize = new IntByReference();
            PBufferSize.setValue(BufferSize);
            PerfData = new Memory(BufferSize);
            PerfData.clear();
        }
        // System.out.println("Final buffer size is " +PBufferSize.getValue());
        if (ret != Pdhdll.ERROR_SUCCESS)
            System.out.println(Integer.toHexString(ret));
        else {
            String key;
            String counter;
            int i = 0;
            while (i < PBufferSize.getValue()) {
                key = PerfData.getString(i);
                i += key.length() + 1;
                counter = PerfData.getString(i);
                i += counter.length() + 1;
                // System.out.println(counter+":"+key);
                if (counter.length() > 0 && key.length() > 0)
                    try {
                        _indexes.put(counter, new Integer(Integer.parseInt(key)));
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
            }

        }
        Advapi32.INSTANCE.RegCloseKey(hkey.getValue());

    }

    /**
     * Translate.
     * 
     * @param name
     *            the name
     * 
     * @return the string
     */
    static String translate(String name) {
        readIndexMap();
        Integer index = (Integer) _indexes.get(name);
        if (index == null)
            return name;
        Memory buff = new Memory(256);
        IntByReference buffSize = new IntByReference();
        buffSize.setValue(256);
        if (Pdhdll.INSTANCE.PdhLookupPerfNameByIndexA(null, index.intValue(), buff,
                buffSize) == Pdhdll.ERROR_SUCCESS)
            return buff.getString(0);
        return name;
    }

    /**
     * Read process map.
     * 
     * @return the map
     */
    static Map readProcessMap() {
        Map result = new HashMap();
        List processes = enumObjectItems("Process", true);
        for (Iterator it = processes.iterator(); it.hasNext();) {
            String process = (String) it.next();
            PdhCounter c = getEnglishCounter("\\Process(" + process + ")\\ID Process");
            int pid = c.getIntValue();
            c.close();
            result.put(new Integer(pid), process);
        }

        return result;

    }

    /**
     * Gets the english counter.
     * 
     * @param counter
     *            the counter
     * 
     * @return the english counter
     */
    static public PdhCounter getEnglishCounter(String counter) {
        if (counter.startsWith("\\PhysicalDisk"))
            if (counter.endsWith("\\% free space") || counter.endsWith("\\free space")
                    || counter.endsWith("\\used space") || counter.endsWith("\\total space"))
                return new HddCounter(counter);
        return new Counter(counter, true);
    }

    /**
     * Gets the locale counter.
     * 
     * @param counter
     *            the counter
     * 
     * @return the locale counter
     */
    static public PdhCounter getLocaleCounter(String counter) {
        return new Counter(counter, false);
    }

    /**
     * Gets the process english counter.
     * 
     * @param pid
     *            the pid
     * @param counter
     *            the counter
     * 
     * @return the process english counter
     */
    static public PdhCounter getProcessEnglishCounter(int pid, String counter) {
        Map m = readProcessMap();
        String process = (String) m.get(new Integer(pid));
        if (process == null)
            return null;
        return getEnglishCounter("\\Process(" + process + ")\\" + counter);
    }

    /**
     * Gets the process locale counter.
     * 
     * @param pid
     *            the pid
     * @param counter
     *            the counter
     * 
     * @return the process locale counter
     */
    static public PdhCounter getProcessLocaleCounter(int pid, String counter) {
        Map m = readProcessMap();
        String processObject = translate("Process");
        String process = (String) m.get(new Integer(pid));
        if (process == null)
            return null;
        return getLocaleCounter("\\" + processObject + "(" + process + ")\\" + counter);
    }

}