/*
 * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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 General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include "jni.h"
#include "jni_util.h"
#include "jlong.h"
#include "jvm.h"
#include "management_ext.h"
#include "com_sun_management_internal_OperatingSystemImpl.h"

#include <psapi.h>
#include <errno.h>
#include <stdlib.h>

#include <malloc.h>
#pragma warning (push,0)
#include <windows.h>
#pragma warning (pop)
#include <stdio.h>
#include <time.h>
#include <stdint.h>
#include <assert.h>

/* Disable warnings due to broken header files from Microsoft... */
#pragma warning(push, 3)
#include <pdh.h>
#include <pdhmsg.h>
#include <process.h>
#pragma warning(pop)

#include <sysinfoapi.h>

typedef unsigned __int32 juint;
typedef unsigned __int64 julong;

static void set_low(jlong* value, jint low) {
    *value &= (jlong)0xffffffff << 32;
    *value |= (jlong)(julong)(juint)low;
}

static void set_high(jlong* value, jint high) {
    *value &= (jlong)(julong)(juint)0xffffffff;
    *value |= (jlong)high       << 32;
}

static jlong jlong_from(jint h, jint l) {
    jlong result = 0; // initialization to avoid warning
    set_high(&result, h);
    set_low(&result,  l);
    return result;
}

static HANDLE main_process;

static void perfInit(void);

JNIEXPORT void JNICALL
Java_com_sun_management_internal_OperatingSystemImpl_initialize0
  (JNIEnv *env, jclass cls)
{
    main_process = GetCurrentProcess();
    perfInit();
}

JNIEXPORT jlong JNICALL
Java_com_sun_management_internal_OperatingSystemImpl_getCommittedVirtualMemorySize0
  (JNIEnv *env, jobject mbean)
{
    PROCESS_MEMORY_COUNTERS pmc;
    if (GetProcessMemoryInfo(main_process, &pmc, sizeof(PROCESS_MEMORY_COUNTERS)) == 0) {
        return (jlong)-1L;
    } else {
        return (jlong) pmc.PagefileUsage;
    }
}

JNIEXPORT jlong JNICALL
Java_com_sun_management_internal_OperatingSystemImpl_getTotalSwapSpaceSize0
  (JNIEnv *env, jobject mbean)
{
    MEMORYSTATUSEX ms;
    ms.dwLength = sizeof(ms);
    GlobalMemoryStatusEx(&ms);
    return (jlong) ms.ullTotalPageFile;
}

JNIEXPORT jlong JNICALL
Java_com_sun_management_internal_OperatingSystemImpl_getFreeSwapSpaceSize0
  (JNIEnv *env, jobject mbean)
{
    MEMORYSTATUSEX ms;
    ms.dwLength = sizeof(ms);
    GlobalMemoryStatusEx(&ms);
    return (jlong) ms.ullAvailPageFile;
}

JNIEXPORT jlong JNICALL
Java_com_sun_management_internal_OperatingSystemImpl_getProcessCpuTime0
  (JNIEnv *env, jobject mbean)
{

    FILETIME process_creation_time, process_exit_time,
             process_user_time, process_kernel_time;

    // Using static variables declared above
    // Units are 100-ns intervals.  Convert to ns.
    GetProcessTimes(main_process, &process_creation_time,
                    &process_exit_time,
                    &process_kernel_time, &process_user_time);
    return (jlong_from(process_user_time.dwHighDateTime,
                        process_user_time.dwLowDateTime) +
            jlong_from(process_kernel_time.dwHighDateTime,
                        process_kernel_time.dwLowDateTime)) * 100;
}

JNIEXPORT jlong JNICALL
Java_com_sun_management_internal_OperatingSystemImpl_getFreeMemorySize0
  (JNIEnv *env, jobject mbean)
{
    MEMORYSTATUSEX ms;
    ms.dwLength = sizeof(ms);
    GlobalMemoryStatusEx(&ms);
    return (jlong) ms.ullAvailPhys;
}

JNIEXPORT jlong JNICALL
Java_com_sun_management_internal_OperatingSystemImpl_getTotalMemorySize0
  (JNIEnv *env, jobject mbean)
{
    MEMORYSTATUSEX ms;
    ms.dwLength = sizeof(ms);
    GlobalMemoryStatusEx(&ms);
    return (jlong) ms.ullTotalPhys;
}

/* Performance Data Helper API (PDH) support */

typedef PDH_STATUS (WINAPI *PdhAddCounterFunc)(
                           HQUERY      hQuery,
                           LPCSTR      szFullCounterPath,
                           DWORD       dwUserData,
                           HCOUNTER    *phCounter
                           );
typedef PDH_STATUS (WINAPI *PdhOpenQueryFunc)(
                           LPCWSTR     szDataSource,
                           DWORD       dwUserData,
                           HQUERY      *phQuery
                           );
typedef PDH_STATUS (WINAPI *PdhCollectQueryDataFunc)(
                           HQUERY      hQuery
                           );

typedef PDH_STATUS (WINAPI *PdhEnumObjectItemsFunc)(
                           LPCTSTR     szDataSource,
                           LPCTSTR     szMachineName,
                           LPCTSTR     szObjectName,
                           LPTSTR      mszCounterList,
                           LPDWORD     pcchCounterListLength,
                           LPTSTR      mszInstanceList,
                           LPDWORD     pcchInstanceListLength,
                           DWORD       dwDetailLevel,
                           DWORD       dwFlags
                           );
typedef PDH_STATUS (WINAPI *PdhRemoveCounterFunc)(
                           HCOUNTER   hCounter
                           );
typedef PDH_STATUS (WINAPI *PdhLookupPerfNameByIndexFunc)(
                           LPCSTR     szMachineName,
                           DWORD      dwNameIndex,
                           LPSTR      szNameBuffer,
                           LPDWORD    pcchNameBufferSize
                           );
typedef DWORD (WINAPI *PdhCloseQueryFunc)(
                      HQUERY      hQuery
                      );

typedef DWORD (WINAPI *PdhGetFormattedCounterValueFunc)(
                      HCOUNTER                hCounter,
                      DWORD                   dwFormat,
                      LPDWORD                 lpdwType,
                      PPDH_FMT_COUNTERVALUE   pValue
                      );

static PdhAddCounterFunc PdhAddCounter_i;
static PdhOpenQueryFunc PdhOpenQuery_i;
static PdhCloseQueryFunc PdhCloseQuery_i;
static PdhCollectQueryDataFunc PdhCollectQueryData_i;
static PdhGetFormattedCounterValueFunc PdhGetFormattedCounterValue_i;
static PdhEnumObjectItemsFunc PdhEnumObjectItems_i;
static PdhRemoveCounterFunc PdhRemoveCounter_i;
static PdhLookupPerfNameByIndexFunc PdhLookupPerfNameByIndex_i;

/*
 * Struct for PDH queries.
 */
typedef struct {
    HQUERY      query;
    uint64_t    lastUpdate; // Last time query was updated (millis)
} UpdateQueryS, *UpdateQueryP;

// Min time between query updates (millis)
static const int MIN_UPDATE_INTERVAL = 500;

/*
 * Struct for a PDH query with multiple counters.
 */
typedef struct {
    UpdateQueryS  query;
    HCOUNTER*     counters;
    int           noOfCounters;
} MultipleCounterQueryS, *MultipleCounterQueryP;

/*
 * Struct for a PDH query with a single counter.
 */
typedef struct {
    UpdateQueryS  query;
    HCOUNTER      counter;
} SingleCounterQueryS, *SingleCounterQueryP;


typedef struct {
    CRITICAL_SECTION cs;
    DWORD owningThread;
    DWORD recursionCount;
} PdhCriticalSectionS, *PdhCriticalSectionP;

static PdhCriticalSectionS initializationLock;

static void InitializePdhCriticalSection(PdhCriticalSectionP criticalSection) {
    assert(criticalSection);

    InitializeCriticalSection(&criticalSection->cs);
    criticalSection->owningThread = 0;
    criticalSection->recursionCount = 0;
}

static void EnterPdhCriticalSection(PdhCriticalSectionP criticalSection) {
    assert(criticalSection);

    EnterCriticalSection(&criticalSection->cs);
    criticalSection->recursionCount++;
    if (!criticalSection->owningThread) {
        criticalSection->owningThread = GetCurrentThreadId();
    }
}

static void LeavePdhCriticalSection(PdhCriticalSectionP criticalSection) {
    assert(criticalSection);
    assert(GetCurrentThreadId() == criticalSection->owningThread);
    assert(criticalSection->recursionCount >= 1);

    criticalSection->recursionCount--;
    if (!criticalSection->recursionCount) {
        criticalSection->owningThread = 0;
    }
    LeaveCriticalSection(&criticalSection->cs);
}

/*
 * INFO: Using PDH APIs Correctly in a Localized Language (Q287159)
 *   http://support.microsoft.com/default.aspx?scid=kb;EN-US;q287159
 * The index value for the base system counters and objects like processor,
 * process, thread, memory, and so forth are always the same irrespective
 * of the localized version of the operating system or service pack installed.
 * To find the correct index for an object or counter, inspect the registry key/value:
 * [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009\Counter]
 */
static const DWORD PDH_PROCESSOR_IDX = 238;
static const DWORD PDH_PROCESSOR_TIME_IDX = 6;
static const DWORD PDH_PROCESS_IDX = 230;
static const DWORD PDH_ID_PROCESS_IDX = 784;

/* PDH format patterns, and lengths of their constant component. */
static const char* const OBJECT_COUNTER_FMT = "\\%s\\%s";
static const size_t OBJECT_COUNTER_FMT_LEN = 2;
static const char* const OBJECT_WITH_INSTANCES_COUNTER_FMT = "\\%s(%s)\\%s";
static const size_t OBJECT_WITH_INSTANCES_COUNTER_FMT_LEN = 4;
static const char* const PROCESS_OBJECT_INSTANCE_COUNTER_FMT = "\\%s(%s#%s)\\%s";
static const size_t PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN = 5;

static const char* pdhProcessImageName = NULL; /* "java" */
static char* pdhIDProcessCounterFmt = NULL;    /* "\Process(java#%d)\ID Process" */

static int numberOfJavaProcessesAtInitialization = 0;

/*
 * Currently used CPU queries/counters and variables
 */
static SingleCounterQueryP processTotalCPULoad = NULL;
static MultipleCounterQueryP multiCounterCPULoad = NULL;
static double cpuFactor = .0;
static DWORD  numCpus = 0;

/*
 * Seems WinXP PDH returns PDH_MORE_DATA whenever we send in a NULL buffer.
 * Let's just ignore it, since we make sure we have enough buffer anyway.
 */
static int
pdhFail(PDH_STATUS pdhStat) {
    return pdhStat != ERROR_SUCCESS && pdhStat != PDH_MORE_DATA;
}

static const char*
allocateAndCopy(const char* const originalString) {
    size_t len;
    char* allocatedString;

    assert(originalString);

    len = strlen(originalString);

    allocatedString = malloc(len + 1);

    if (!allocatedString) {
        return NULL;
    }

    strncpy(allocatedString, originalString, len);
    allocatedString[len] = '\0';

    return allocatedString;
}

/*
 * Allocates memory into the supplied pointer and
 * fills it with the localized PDH artifact description, if indexed correctly.
 * Caller owns the memory from the point of returning from this function.
 *
 * @param index    the PDH counter index as specified in the registry
 * @param ppBuffer pointer to a char*.
 * @return         0 if successful, negative on failure.
 */
static int
lookupNameByIndex(DWORD index, char** ppBuffer) {
    DWORD size;

    assert(ppBuffer);

    /* determine size needed */
    if (PdhLookupPerfNameByIndex_i(NULL, index, NULL, &size) != PDH_MORE_DATA) {
      /* invalid index? */
      return -1;
    }

    *ppBuffer = malloc((size_t)size);

    if (!*ppBuffer) {
        return -1;
    }

    if (PdhLookupPerfNameByIndex_i(NULL, index, *ppBuffer, &size) != ERROR_SUCCESS) {
        free(*ppBuffer);
        *ppBuffer = NULL;
        return -1;
    }

    /* windows vista does not null-terminate the string
     * (although the docs says it will) */
    (*ppBuffer)[size - 1] = '\0';

    return 0;
}

/*
* Construct a fully qualified PDH path
*
* @param objectName   a PDH Object string representation (required)
* @param counterName  a PDH Counter string representation (required)
* @param imageName    a process image name string, ex. "java" (opt)
* @param instance     an instance string, ex. "0", "1", ... (opt)
* @return             the fully qualified PDH path.
*
* Caller will own the returned malloc:ed string
*/
static const char*
makeFullCounterPath(const char* const objectName,
                    const char* const counterName,
                    const char* const imageName,
                    const char* const instance) {

    size_t fullCounterPathLen;
    char* fullCounterPath;

    assert(objectName);
    assert(counterName);

    // Always include space for null terminator:
    fullCounterPathLen = strlen(objectName) + strlen(counterName) + 1;

    if (imageName) {
        /*
         * For paths using the "Process" Object.
         *
         * Examples:
         * abstract: "\Process(imageName#instance)\Counter"
         * actual:   "\Process(java#2)\ID Process"
         */
        fullCounterPathLen += PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN;
        fullCounterPathLen += strlen(imageName);

        /*
         * imageName must be passed together with an associated
         * instance "number" ("0", "1", "2", ...).
         * This is required in order to create valid "Process" Object paths.
         *
         * Examples: "\Process(java#0)", \Process(java#1"), ...
         */
        assert(instance);

        fullCounterPathLen += strlen(instance);
        fullCounterPath = malloc(fullCounterPathLen);

        if (!fullCounterPath) {
            return NULL;
        }

        snprintf(fullCounterPath,
                 fullCounterPathLen,
                 PROCESS_OBJECT_INSTANCE_COUNTER_FMT,
                 objectName,
                 imageName,
                 instance,
                 counterName);
    } else {
        if (instance) {
            /*
             * For paths where the Object has multiple instances.
             *
             * Examples:
             * abstract: "\Object(instance)\Counter"
             * actual:   "\Processor(0)\% Privileged Time"
             */
            fullCounterPathLen += strlen(instance);
            fullCounterPathLen += OBJECT_WITH_INSTANCES_COUNTER_FMT_LEN;
        } else {
            /*
             * For "normal" paths.
             *
             * Examples:
             * abstract: "\Object\Counter"
             * actual:   "\Memory\Available Mbytes"
             */
            fullCounterPathLen += OBJECT_COUNTER_FMT_LEN;
        }

        fullCounterPath = malloc(fullCounterPathLen);

        if (!fullCounterPath) {
            return NULL;
        }

        if (instance) {
            snprintf(fullCounterPath,
                     fullCounterPathLen,
                     OBJECT_WITH_INSTANCES_COUNTER_FMT,
                     objectName,
                     instance,
                     counterName);
        } else {
            snprintf(fullCounterPath,
                     fullCounterPathLen,
                     OBJECT_COUNTER_FMT,
                     objectName,
                     counterName);
        }
    }

    return fullCounterPath;
}

/*
 * Resolves an index for a PDH artifact to
 * a localized, malloc:ed string representation.
 * Caller will own the returned malloc:ed string.
 *
 * @param pdhArtifactIndex  PDH index
 * @return                  malloc:ed string representation
 *                          of the requested pdh artifact (localized).
 *                          NULL on failure.
 */
static const char*
getPdhLocalizedArtifact(DWORD pdhArtifactIndex) {
    char* pdhLocalizedArtifactString;

    if (lookupNameByIndex(pdhArtifactIndex,
                          &pdhLocalizedArtifactString) != 0) {
        return NULL;
    }

    return pdhLocalizedArtifactString;
}

static void
pdhCleanup(HQUERY* const query, HCOUNTER* const counter) {
    if (counter && *counter) {
        PdhRemoveCounter_i(*counter);
        *counter = NULL;
    }
    if (query && *query) {
        PdhCloseQuery_i(*query);
        *query = NULL;
    }
}

static void
destroySingleCounter(SingleCounterQueryP counterQuery) {
    if (counterQuery) {
        pdhCleanup(&counterQuery->query.query, &counterQuery->counter);
    }
}

static void
destroyMultiCounter(MultipleCounterQueryP multiCounterQuery) {
    int i;
    if (multiCounterQuery) {
        if (multiCounterQuery->counters) {
            for (i = 0; i < multiCounterQuery->noOfCounters; i++) {
                pdhCleanup(NULL, &multiCounterQuery->counters[i]);
            }
            free(multiCounterQuery->counters);
            multiCounterQuery->counters = NULL;
        }
        pdhCleanup(&multiCounterQuery->query.query, NULL);
    }
}

static int
openQuery(HQUERY* const query) {
    assert(query);

    if (PdhOpenQuery_i(NULL, 0, query) != ERROR_SUCCESS) {
        return -1;
    }

    return 0;
}

static int
addCounter(HQUERY query,
           const char* const fullCounterPath,
           HCOUNTER* const counter) {

    assert(fullCounterPath);
    assert(counter);

    if (PdhAddCounter_i(query,
                        fullCounterPath,
                        0,
                        counter) != ERROR_SUCCESS) {
        return -1;
    }

    return 0;
}

/*
 * Sets up the supplied SingleCounterQuery to listen for the specified counter.
 *
 * @param counterQuery       the counter query to set up.
 * @param fullCounterPath    the string specifying the full path to the counter.
 * @returns                  0 if successful, negative on failure.
 */
static int
initializeSingleCounterQuery(SingleCounterQueryP counterQuery,
                             const char* const fullCounterPath) {
    assert(counterQuery);
    assert(fullCounterPath);

    if (openQuery(&counterQuery->query.query) == 0) {
        if (addCounter(counterQuery->query.query,
                       fullCounterPath,
                       &counterQuery->counter) == 0) {
            return 0;
        }
    }

    return -1;
}

/*
 * Sets up a SingleCounterQuery
 *
 * param counter             the counter query to set up.
 * param localizedObject     string representing the PDH object to query
 * param localizedCounter    string representing the PDH counter to query
 * param processImageName    if the counter query needs the process image name ("java")
 * param instance            if the counter has instances, this is the instance ("\Processor(0)\")
                                 where 0 is the instance
 * param firstSampleOnInit   for counters that need two queries to yield their values,
                                 the first query can be issued just after initialization
 *
 * @returns                   0 if successful, negative on failure.
 */
static int
initializeSingleCounter(SingleCounterQueryP const counter,
                        const char* const localizedObject,
                        const char* const localizedCounter,
                        const char* const processImageName,
                        const char* const instance,
                        BOOL firstSampleOnInit) {
    int retValue = -1;

    const char* fullCounterPath = makeFullCounterPath(localizedObject,
                                                      localizedCounter,
                                                      processImageName,
                                                      instance);

    if (fullCounterPath) {

        assert(counter);

        if (initializeSingleCounterQuery(counter, fullCounterPath) == 0) {
            /*
             * According to the MSDN documentation, rate counters must be read twice:
             *
             * "Obtaining the value of rate counters such as Page faults/sec requires that
             *  PdhCollectQueryData be called twice, with a specific time interval between
             *  the two calls, before calling PdhGetFormattedCounterValue. Call Sleep to
             *  implement the waiting period between the two calls to PdhCollectQueryData."
             *
             *  Take the first sample here already to allow for the next (first) "real" sample
             *  to succeed.
             */
            if (firstSampleOnInit) {
                PdhCollectQueryData_i(counter->query.query);
            }

            retValue = 0;
        }
        free((char*)fullCounterPath);
    }

    return retValue;
}

static void
perfInit(void) {
    InitializePdhCriticalSection(&initializationLock);
}

static int
getProcessID() {
    static int myPid = 0;
    if (0 == myPid) {
        myPid = _getpid();
    }
    return myPid;
}

/*
 * Working against the Process object and it's related counters is inherently problematic
 * when using the PDH API:
 *
 * For PDH, a process is not primarily identified by it's process id,
 * but with a sequential number, for example \Process(java#0), \Process(java#1), ....
 * The really bad part is that this list is reset as soon as one process exits:
 * If \Process(java#1) exits, \Process(java#3) now becomes \Process(java#2) etc.
 *
 * The PDH query api requires a process identifier to be submitted when registering
 * a query, but as soon as the list resets, the query is invalidated (since the name
 * changed).
 *
 * Solution:
 * The #number identifier for a Process query can only decrease after process creation.
 *
 * Therefore we create an array of counter queries for all process object instances
 * up to and including ourselves:
 *
 * Ex. we come in as third process instance (java#2), we then create and register
 * queries for the following Process object instances:
 * java#0, java#1, java#2
 *
 * currentQueryIndexForProcess() keeps track of the current "correct" query
 * (in order to keep this index valid when the list resets from underneath,
 * ensure to call getCurrentQueryIndexForProcess() before every query involving
 * Process object instance data).
 *
 * Returns -1 on failure.
 */
static int
currentQueryIndexForProcess(void) {
    HQUERY tmpQuery = NULL;
    HCOUNTER handleCounter = NULL;
    int retValue = -1;

    assert(pdhProcessImageName);
    assert(pdhIDProcessCounterFmt);

    if (openQuery(&tmpQuery) == 0) {
        int index;

        /* iterate over all instance indexes and try to find our own pid */
        for (index = 0; index < INT_MAX; ++index) {
            char fullIDProcessCounterPath[MAX_PATH];
            PDH_FMT_COUNTERVALUE counterValue;
            PDH_STATUS res;

            snprintf(fullIDProcessCounterPath,
                     MAX_PATH,
                     pdhIDProcessCounterFmt,
                     index);

            if (addCounter(tmpQuery, fullIDProcessCounterPath, &handleCounter) != 0) {
                break;
            }

            res = PdhCollectQueryData_i(tmpQuery);

            if (PDH_INVALID_HANDLE == res || PDH_NO_DATA == res) {
                break;
            }

            PdhGetFormattedCounterValue_i(handleCounter,
                                          PDH_FMT_LONG,
                                          NULL,
                                          &counterValue);
            /*
             * This check seems to be needed for Win2k SMP boxes, since
             * they for some reason don't return PDH_NO_DATA for non existing
             * counters.
             */
            if (counterValue.CStatus != PDH_CSTATUS_VALID_DATA) {
                break;
            }

            if ((LONG)getProcessID() == counterValue.longValue) {
                retValue = index;
                break;
            }
        }
    }

    pdhCleanup(&tmpQuery, &handleCounter);

    return retValue;
}

/*
 * If successful, returns the #index corresponding to our PID
 * as resolved by the pdh query:
 * "\Process(java#index)\ID Process" (or localized equivalent)
 *
 * This function should be called before attempting to read
 * from any Process related counter(s), and the return value
 * is the index to be used for indexing an array of Process object query's:
 *
 * Example:
 * processTotalCPULoad[currentQueryIndex].query
 *
 * Returns -1 on failure.
 */
static int
getCurrentQueryIndexForProcess() {
    int currentQueryIndex = currentQueryIndexForProcess();

    assert(currentQueryIndex < numberOfJavaProcessesAtInitialization);

    return currentQueryIndex;
}

/*
 * Returns the PDH string identifying the current process image name.
 * Use this name as a qualifier when getting counters from the PDH Process Object
 * representing your process.

 * Example:
 * "\Process(java#0)\Virtual Bytes" - where "java" is the PDH process
 * image name.
 *
 * Please note that the process image name is not necessarily "java",
 * hence the use of GetModuleFileName() to detect the process image name.
 *
 * @return   the process image name to be used when retrieving
 *           PDH counters from the current process. The caller will
             own the returned malloc:ed string. NULL if failure.
 */
static const char*
getPdhProcessImageName() {
    char moduleName[MAX_PATH];
    char* processImageName;
    char* dotPos;

    // Find our module name and use it to extract the image name used by PDH
    DWORD getmfnReturn = GetModuleFileName(NULL, moduleName, sizeof(moduleName));

    if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
        return NULL;
    }

    if (getmfnReturn >= MAX_PATH || 0 == getmfnReturn) {
        return NULL;
    }

    processImageName = strrchr(moduleName, '\\'); //drop path
    processImageName++;                           //skip slash
    dotPos = strrchr(processImageName, '.');      //drop .exe
    dotPos[0] = '\0';

    return allocateAndCopy(processImageName);
}

/*
 * Sets up the supplied MultipleCounterQuery to check on the processors via PDH CPU counters.
 * TODO: Refactor and prettify as with the SingleCounter queries
 * if more MultipleCounterQueries are discovered/needed.
 *
 * @param multiCounterCPULoad  a pointer to a MultipleCounterQueryS, will be filled in with
 *                             the necessary info to check the PDH processor counters.
 * @return                     0 if successful, negative on failure.
 */
static int
initializeMultipleCounterForCPUs(MultipleCounterQueryP multiCounterCPULoad) {
    DWORD cSize = 0;
    DWORD iSize = 0;
    DWORD pCount;
    DWORD index;
    char* processor = NULL; //'Processor' == PDH_PROCESSOR_IDX
    char* time = NULL;      //'Time' == PDH_PROCESSOR_TIME_IDX
    char* instances = NULL;
    char* tmp;
    int   retValue = -1;
    PDH_STATUS pdhStat;

    if (lookupNameByIndex(PDH_PROCESSOR_IDX, &processor) != 0) {
        goto end;
    }

    if (lookupNameByIndex(PDH_PROCESSOR_TIME_IDX, &time) != 0) {
        goto end;
    }

    //ok, now we have enough to enumerate all processors.
    pdhStat = PdhEnumObjectItems_i(
                                   NULL, // reserved
                                   NULL, // local machine
                                   processor, // object to enumerate
                                   NULL, // pass in NULL buffers
                                   &cSize, // and 0 length to get
                                   NULL, // required size
                                   &iSize, // of the buffers in chars
                                   PERF_DETAIL_WIZARD, // counter detail level
                                   0);

    if (pdhFail(pdhStat)) {
        goto end;
    }

    instances = calloc(iSize, 1);

    if (!instances) {
        goto end;
    }

    cSize = 0;

    pdhStat = PdhEnumObjectItems_i(
                                   NULL, // reserved
                                   NULL, // local machine
                                   processor, // object to enumerate
                                   NULL, // pass in NULL buffers
                                   &cSize,
                                   instances, // now allocated to be filled in
                                   &iSize, // and size is known
                                   PERF_DETAIL_WIZARD, // counter detail level
                                   0);

    if (pdhFail(pdhStat)) {
        goto end;
    }

    // enumerate the Processor instances ("\Processor(0)", "\Processor(1)", ..., "\Processor(_Total)")
    for (pCount = 0, tmp = instances; *tmp != '\0'; tmp = &tmp[strlen(tmp)+1], pCount++);

    assert(pCount == numCpus+1);

    //ok, we now have the number of Processor instances - allocate an HCOUNTER for each
    multiCounterCPULoad->counters = (HCOUNTER*)malloc(pCount * sizeof(HCOUNTER));

    if (!multiCounterCPULoad->counters) {
        goto end;
    }

    multiCounterCPULoad->noOfCounters = pCount;

    if (openQuery(&multiCounterCPULoad->query.query) != 0) {
        goto end;
    }

    // fetch instance and register its corresponding HCOUNTER with the query
    for (index = 0, tmp = instances; *tmp != '\0'; tmp = &tmp[strlen(tmp)+1], ++index) {
        const char* const fullCounterPath = makeFullCounterPath(processor, time, NULL, tmp);

        if (!fullCounterPath) {
            goto end;
        }

        retValue = addCounter(multiCounterCPULoad->query.query,
                              fullCounterPath,
                              &multiCounterCPULoad->counters[index]);

        free((char*)fullCounterPath);

        if (retValue != 0) {
            goto end;
        }
    }

    // Query once to initialize the counters which require at least two samples
    // (like the % CPU usage) to calculate correctly.
    PdhCollectQueryData_i(multiCounterCPULoad->query.query);

  end:
    if (processor) {
        free(processor);
    }

    if (time) {
        free(time);
    }

    if (instances) {
        free(instances);
    }

    return retValue;
}

/*
 * Dynamically sets up function pointers to the PDH library.
 *
 * @param h  HMODULE for the PDH library
 * @return   0 on success, negative on failure.
 */
static int
bindPdhFunctionPointers(HMODULE h) {
    assert(h);
    assert(GetCurrentThreadId() == initializationLock.owningThread);

    /* The 'A' at the end means the ANSI (not the UNICODE) versions of the methods */
    PdhAddCounter_i         = (PdhAddCounterFunc)GetProcAddress(h, "PdhAddCounterA");
    PdhOpenQuery_i         = (PdhOpenQueryFunc)GetProcAddress(h, "PdhOpenQueryA");
    PdhCloseQuery_i         = (PdhCloseQueryFunc)GetProcAddress(h, "PdhCloseQuery");
    PdhCollectQueryData_i     = (PdhCollectQueryDataFunc)GetProcAddress(h, "PdhCollectQueryData");
    PdhGetFormattedCounterValue_i = (PdhGetFormattedCounterValueFunc)GetProcAddress(h, "PdhGetFormattedCounterValue");
    PdhEnumObjectItems_i         = (PdhEnumObjectItemsFunc)GetProcAddress(h, "PdhEnumObjectItemsA");
    PdhRemoveCounter_i         = (PdhRemoveCounterFunc)GetProcAddress(h, "PdhRemoveCounter");
    PdhLookupPerfNameByIndex_i     = (PdhLookupPerfNameByIndexFunc)GetProcAddress(h, "PdhLookupPerfNameByIndexA");

    if (!PdhAddCounter_i || !PdhOpenQuery_i ||
        !PdhCloseQuery_i || !PdhCollectQueryData_i ||
        !PdhGetFormattedCounterValue_i || !PdhEnumObjectItems_i ||
        !PdhRemoveCounter_i || !PdhLookupPerfNameByIndex_i)
    {
        return -1;
    }
    return 0;
}

/*
 * Returns the counter value as a double for the specified query.
 * Will collect the query data and update the counter values as necessary.
 *
 * @param query       the query to update (if needed).
 * @param c           the counter to read.
 * @param value       where to store the formatted value.
 * @param format      the format to use (i.e. PDH_FMT_DOUBLE, PDH_FMT_LONG etc)
 * @return            0 if no error
 *                    -1 if PdhCollectQueryData fails
 *                    -2 if PdhGetFormattedCounterValue fails
 */
static int
getPerformanceData(UpdateQueryP query, HCOUNTER c, PDH_FMT_COUNTERVALUE* value, DWORD format) {
    uint64_t now = GetTickCount64();

    /*
     * Need to limit how often we update the query
     * to minimize the Heisenberg effect.
     * (PDH behaves erratically if the counters are
     * queried too often, especially counters that
     * store and use values from two consecutive updates,
     * like cpu load.)
     */
    if (now - query->lastUpdate > MIN_UPDATE_INTERVAL) {
        if (PdhCollectQueryData_i(query->query) != ERROR_SUCCESS) {
            return -1;
        }
        query->lastUpdate = now;
    }

    if (PdhGetFormattedCounterValue_i(c, format, NULL, value) != ERROR_SUCCESS) {
        return -2;
    }

    return 0;
}

static int
allocateAndInitializePdhConstants() {
    const char* pdhLocalizedProcessObject = NULL;
    const char* pdhLocalizedIDProcessCounter = NULL;
    size_t pdhIDProcessCounterFmtLen;
    int currentQueryIndex;
    int retValue = -1;

    assert(GetCurrentThreadId() == initializationLock.owningThread);

    assert(!pdhProcessImageName);
    pdhProcessImageName = getPdhProcessImageName();
    if (!pdhProcessImageName) {
        goto end;
    }

    pdhLocalizedProcessObject = getPdhLocalizedArtifact(PDH_PROCESS_IDX);
    if (!pdhLocalizedProcessObject) {
        goto end;
    }

    pdhLocalizedIDProcessCounter = getPdhLocalizedArtifact(PDH_ID_PROCESS_IDX);
    if (!pdhLocalizedIDProcessCounter) {
        goto end;
    }

    assert(!pdhIDProcessCounterFmt);

    pdhIDProcessCounterFmtLen = strlen(pdhProcessImageName);
    pdhIDProcessCounterFmtLen += strlen(pdhLocalizedProcessObject);
    pdhIDProcessCounterFmtLen += strlen(pdhLocalizedIDProcessCounter);
    pdhIDProcessCounterFmtLen += PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN;
    pdhIDProcessCounterFmtLen += 3; // "%d" and '\0'

    assert(pdhIDProcessCounterFmtLen < MAX_PATH);
    pdhIDProcessCounterFmt = malloc(pdhIDProcessCounterFmtLen);
    if (!pdhIDProcessCounterFmt) {
        goto end;
    }

    /* "\Process(java#%d)\ID Process" */
    snprintf(pdhIDProcessCounterFmt,
             pdhIDProcessCounterFmtLen,
             PROCESS_OBJECT_INSTANCE_COUNTER_FMT,
             pdhLocalizedProcessObject,
             pdhProcessImageName,
             "%d",
             pdhLocalizedIDProcessCounter);

    assert(0 == numberOfJavaProcessesAtInitialization);
    currentQueryIndex = currentQueryIndexForProcess();
    if (-1 == currentQueryIndex) {
        goto end;
    }

    numberOfJavaProcessesAtInitialization = currentQueryIndex + 1;
    assert(numberOfJavaProcessesAtInitialization >= 1);

    retValue = 0;

  end:

    if (pdhLocalizedProcessObject) {
        free((char*)pdhLocalizedProcessObject);
    }

    if (pdhLocalizedIDProcessCounter) {
        free((char*)pdhLocalizedIDProcessCounter);
    }

    return retValue;
}

static void
deallocatePdhConstants() {
    assert(GetCurrentThreadId() == initializationLock.owningThread);

    if (pdhProcessImageName) {
        free((char*)pdhProcessImageName);
        pdhProcessImageName = NULL;
    }

    if (pdhIDProcessCounterFmt) {
      free(pdhIDProcessCounterFmt);
      pdhIDProcessCounterFmt = NULL;
    }

    numberOfJavaProcessesAtInitialization = 0;
}

static int
initializeCPUCounters() {
    SYSTEM_INFO si;
    char* localizedProcessObject;
    char* localizedProcessorTimeCounter;
    int i;
    int retValue = -1;

    assert(GetCurrentThreadId() == initializationLock.owningThread);

    assert(0 == numCpus);
    GetSystemInfo(&si);
    numCpus = si.dwNumberOfProcessors;
    assert(numCpus >= 1);

    /* Initialize the denominator for the jvm load calculations */
    assert(.0 == cpuFactor);
    cpuFactor = numCpus * 100;

    if (lookupNameByIndex(PDH_PROCESS_IDX,
                          &localizedProcessObject) == 0) {

        if (lookupNameByIndex(PDH_PROCESSOR_TIME_IDX,
                              &localizedProcessorTimeCounter) == 0) {

            assert(processTotalCPULoad);
            assert(pdhProcessImageName);

            for (i = 0; i < numberOfJavaProcessesAtInitialization; ++i) {
                char instanceIndexBuffer[32];
                retValue = initializeSingleCounter(&processTotalCPULoad[i],
                                                   localizedProcessObject,
                                                   localizedProcessorTimeCounter,
                                                   pdhProcessImageName,
                                                   itoa(i, instanceIndexBuffer, 10),
                                                   TRUE);
                if (retValue != 0) {
                    break;
                }
            }
            free(localizedProcessorTimeCounter);
        }
        free(localizedProcessObject);
    }

    if (retValue != 0) {
        return -1;
    }

    assert(multiCounterCPULoad);
    return initializeMultipleCounterForCPUs(multiCounterCPULoad);
}

static void
deallocateCPUCounters() {
    int i;

    assert(GetCurrentThreadId() == initializationLock.owningThread);

    if (processTotalCPULoad) {
        for (i = 0; i < numberOfJavaProcessesAtInitialization; ++i) {
            destroySingleCounter(&processTotalCPULoad[i]);
        }
        free(processTotalCPULoad);
        processTotalCPULoad = NULL;
    }

    if (multiCounterCPULoad) {
        destroyMultiCounter(multiCounterCPULoad);
        free(multiCounterCPULoad);
        multiCounterCPULoad = NULL;
    }

    cpuFactor = .0;
    numCpus = 0;
}

static void
pdhInitErrorHandler(HMODULE h) {
    assert(GetCurrentThreadId() == initializationLock.owningThread);

    deallocatePdhConstants();

    if (h) {
        FreeLibrary(h);
    }
}

/*
 * Helper to initialize the PDH library, function pointers and constants.
 *
 * @return  0 if successful, negative on failure.
 */
static int
pdhInit() {
    static BOOL initialized = FALSE;
    int retValue;

    if (initialized) {
        return 0;
    }

    retValue = 0;

    EnterPdhCriticalSection(&initializationLock); {
        if (!initialized) {
            HMODULE h = NULL;
            if ((h = LoadLibrary("pdh.dll")) == NULL) {
                retValue = -1;
            } else if (bindPdhFunctionPointers(h) < 0) {
                retValue = -1;
            } else if (allocateAndInitializePdhConstants() < 0) {
                retValue = -1;
            }

            if (0 == retValue) {
                initialized = TRUE;
            } else {
                pdhInitErrorHandler(h);
            }
        }
    } LeavePdhCriticalSection(&initializationLock);

    return retValue;
}

static int
allocateCPUCounters() {
    assert(GetCurrentThreadId() == initializationLock.owningThread);
    assert(numberOfJavaProcessesAtInitialization >= 1);
    assert(!processTotalCPULoad);
    assert(!multiCounterCPULoad);

    /*
     * Create an array of Process object queries, for each instance
     * up to and including our own (java#0, java#1, java#2, ...).
     */
    processTotalCPULoad = calloc(numberOfJavaProcessesAtInitialization,
                                 sizeof(SingleCounterQueryS));

    if (!processTotalCPULoad) {
        return -1;
    }

    multiCounterCPULoad = calloc(1, sizeof(MultipleCounterQueryS));

    if (!multiCounterCPULoad) {
        return -1;
    }

    return 0;
}

static int
initializePdhCPUCounters() {
    static BOOL initialized = FALSE;
    int retValue;

    if (initialized) {
        return 0;
    }

    retValue = 0;

    EnterPdhCriticalSection(&initializationLock); {
        if (!initialized) {
            if (pdhInit() < 0) {
                retValue = -1;
            }  else if (allocateCPUCounters() < 0) {
                retValue = -1;
            } else if (initializeCPUCounters() < 0) {
                retValue = -1;
            }

            if (0 == retValue) {
                initialized = TRUE;
            } else {
              deallocateCPUCounters();
            }
        }
    } LeavePdhCriticalSection(&initializationLock);

    return retValue;
}

static int
perfCPUInit() {
    return initializePdhCPUCounters();
}

static double
perfGetProcessCPULoad() {
    PDH_FMT_COUNTERVALUE cv;
    int currentQueryIndex;

    if (perfCPUInit() < 0) {
        // warn?
        return -1.0;
    }

    currentQueryIndex = getCurrentQueryIndexForProcess();
    if (currentQueryIndex >= 0 && getPerformanceData(&processTotalCPULoad[currentQueryIndex].query,
                                                     processTotalCPULoad[currentQueryIndex].counter,
                                                     &cv,
                                                     PDH_FMT_DOUBLE | PDH_FMT_NOCAP100) == 0) {
        double d = cv.doubleValue / cpuFactor;
        d = min(1, d);
        d = max(0, d);
        return d;
    }
    return -1.0;
}

static double
perfGetCPULoad(int which) {
    PDH_FMT_COUNTERVALUE cv;
    HCOUNTER c;

    if (perfCPUInit() < 0) {
        // warn?
        return -1.0;
    }

    if (-1 == which) {
        c = multiCounterCPULoad->counters[multiCounterCPULoad->noOfCounters - 1];
    } else {
        if (which < multiCounterCPULoad->noOfCounters) {
            c = multiCounterCPULoad->counters[which];
        } else {
            return -1.0;
        }
    }
    if (getPerformanceData(&multiCounterCPULoad->query, c, &cv, PDH_FMT_DOUBLE ) == 0) {
        return cv.doubleValue / 100;
    }
    return -1.0;
}

JNIEXPORT jdouble JNICALL
Java_com_sun_management_internal_OperatingSystemImpl_getCpuLoad0
(JNIEnv *env, jobject dummy)
{
    return perfGetCPULoad(-1);
}

JNIEXPORT jdouble JNICALL
Java_com_sun_management_internal_OperatingSystemImpl_getProcessCpuLoad0
(JNIEnv *env, jobject dummy)
{
    return perfGetProcessCPULoad();
}
