123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 |
- /**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with this
- * work for additional information regarding copyright ownership. The ASF
- * licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
- #include "winutils.h"
- #include <psapi.h>
- #include <PowrProf.h>
- #include <pdh.h>
- #include <pdhmsg.h>
- #ifdef PSAPI_VERSION
- #undef PSAPI_VERSION
- #endif
- #define PSAPI_VERSION 1
- #pragma comment(lib, "psapi.lib")
- #pragma comment(lib, "Powrprof.lib")
- #pragma comment(lib, "pdh.lib")
- CONST PWSTR COUNTER_PATH_NET_READ_ALL = L"\\Network Interface(*)\\Bytes Received/Sec";
- CONST PWSTR COUNTER_PATH_NET_WRITE_ALL = L"\\Network Interface(*)\\Bytes Sent/Sec";
- CONST PWSTR COUNTER_PATH_DISK_READ_ALL = L"\\LogicalDisk(*)\\Disk Read Bytes/sec";
- CONST PWSTR COUNTER_PATH_DISK_WRITE_ALL = L"\\LogicalDisk(*)\\Disk Write Bytes/sec";
- typedef struct _PROCESSOR_POWER_INFORMATION {
- ULONG Number;
- ULONG MaxMhz;
- ULONG CurrentMhz;
- ULONG MhzLimit;
- ULONG MaxIdleState;
- ULONG CurrentIdleState;
- } PROCESSOR_POWER_INFORMATION, *PPROCESSOR_POWER_INFORMATION;
- //----------------------------------------------------------------------------
- // Function: SystemInfo
- //
- // Description:
- // Returns the resource information about the machine
- //
- // Returns:
- // EXIT_SUCCESS: On success
- // EXIT_FAILURE: otherwise
- int SystemInfo()
- {
- size_t vmemSize, vmemFree, memSize, memFree;
- PERFORMANCE_INFORMATION memInfo;
- SYSTEM_INFO sysInfo;
- FILETIME idleTimeFt, kernelTimeFt, userTimeFt;
- ULARGE_INTEGER idleTime, kernelTime, userTime;
- ULONGLONG cpuTimeMs;
- size_t size;
- LPBYTE pBuffer;
- PROCESSOR_POWER_INFORMATION const *ppi;
- ULONGLONG cpuFrequencyKhz;
- NTSTATUS status;
- LONGLONG diskRead, diskWrite, netRead, netWrite;
- ZeroMemory(&memInfo, sizeof(PERFORMANCE_INFORMATION));
- memInfo.cb = sizeof(PERFORMANCE_INFORMATION);
- if(!GetPerformanceInfo(&memInfo, sizeof(PERFORMANCE_INFORMATION)))
- {
- ReportErrorCode(L"GetPerformanceInfo", GetLastError());
- return EXIT_FAILURE;
- }
- vmemSize = memInfo.CommitLimit*memInfo.PageSize;
- vmemFree = vmemSize - memInfo.CommitTotal*memInfo.PageSize;
- memSize = memInfo.PhysicalTotal*memInfo.PageSize;
- memFree = memInfo.PhysicalAvailable*memInfo.PageSize;
- GetSystemInfo(&sysInfo);
- if(!GetSystemTimes(&idleTimeFt, &kernelTimeFt, &userTimeFt))
- {
- ReportErrorCode(L"GetSystemTimes", GetLastError());
- return EXIT_FAILURE;
- }
- idleTime.HighPart = idleTimeFt.dwHighDateTime;
- idleTime.LowPart = idleTimeFt.dwLowDateTime;
- kernelTime.HighPart = kernelTimeFt.dwHighDateTime;
- kernelTime.LowPart = kernelTimeFt.dwLowDateTime;
- userTime.HighPart = userTimeFt.dwHighDateTime;
- userTime.LowPart = userTimeFt.dwLowDateTime;
- cpuTimeMs = (kernelTime.QuadPart - idleTime.QuadPart + userTime.QuadPart)/10000;
- // allocate buffer to get info for each processor
- size = sysInfo.dwNumberOfProcessors * sizeof(PROCESSOR_POWER_INFORMATION);
- pBuffer = (BYTE*) LocalAlloc(LPTR, size);
- if(!pBuffer)
- {
- ReportErrorCode(L"LocalAlloc", GetLastError());
- return EXIT_FAILURE;
- }
- status = CallNtPowerInformation(ProcessorInformation, NULL, 0, pBuffer, (long)size);
- if(0 != status)
- {
- fwprintf_s(stderr, L"Error in CallNtPowerInformation. Err:%d\n", status);
- LocalFree(pBuffer);
- return EXIT_FAILURE;
- }
- ppi = (PROCESSOR_POWER_INFORMATION const *)pBuffer;
- cpuFrequencyKhz = ppi->MaxMhz*1000;
- LocalFree(pBuffer);
- status = GetDiskAndNetwork(&diskRead, &diskWrite, &netRead, &netWrite);
- if(0 != status)
- {
- fwprintf_s(stderr, L"Error in GetDiskAndNetwork. Err:%d\n", status);
- return EXIT_FAILURE;
- }
- fwprintf_s(stdout, L"%Iu,%Iu,%Iu,%Iu,%u,%I64u,%I64u,%I64d,%I64d,%I64d,%I64d\n", vmemSize, memSize,
- vmemFree, memFree, sysInfo.dwNumberOfProcessors, cpuFrequencyKhz, cpuTimeMs,
- diskRead, diskWrite, netRead, netWrite);
- return EXIT_SUCCESS;
- }
- void SystemInfoUsage()
- {
- fwprintf(stdout, L"\
- Usage: systeminfo\n\
- Prints machine information on stdout\n\
- Comma separated list of the following values.\n\
- VirtualMemorySize(bytes),PhysicalMemorySize(bytes),\n\
- FreeVirtualMemory(bytes),FreePhysicalMemory(bytes),\n\
- NumberOfProcessors,CpuFrequency(Khz),\n\
- CpuTime(MilliSec,Kernel+User),\n\
- DiskRead(bytes),DiskWrite(bytes),\n\
- NetworkRead(bytes),NetworkWrite(bytes)\n");
- }
- int GetDiskAndNetwork(LONGLONG* diskRead, LONGLONG* diskWrite, LONGLONG* netRead, LONGLONG* netWrite)
- {
- int ret = EXIT_SUCCESS;
- PDH_STATUS status = ERROR_SUCCESS;
- PDH_HQUERY hQuery = NULL;
- PDH_HCOUNTER hCounterNetRead = NULL;
- PDH_HCOUNTER hCounterNetWrite = NULL;
- PDH_HCOUNTER hCounterDiskRead = NULL;
- PDH_HCOUNTER hCounterDiskWrite = NULL;
- DWORD i;
- if(status = PdhOpenQuery(NULL, 0, &hQuery))
- {
- fwprintf_s(stderr, L"PdhOpenQuery failed with 0x%x.\n", status);
- ret = EXIT_FAILURE;
- goto cleanup;
- }
- // Add each one of the counters with wild cards
- if(status = PdhAddCounter(hQuery, COUNTER_PATH_NET_READ_ALL, 0, &hCounterNetRead))
- {
- fwprintf_s(stderr, L"PdhAddCounter %s failed with 0x%x.\n", COUNTER_PATH_NET_READ_ALL, status);
- ret = EXIT_FAILURE;
- goto cleanup;
- }
- if(status = PdhAddCounter(hQuery, COUNTER_PATH_NET_WRITE_ALL, 0, &hCounterNetWrite))
- {
- fwprintf_s(stderr, L"PdhAddCounter %s failed with 0x%x.\n", COUNTER_PATH_NET_WRITE_ALL, status);
- ret = EXIT_FAILURE;
- goto cleanup;
- }
- if(status = PdhAddCounter(hQuery, COUNTER_PATH_DISK_READ_ALL, 0, &hCounterDiskRead))
- {
- fwprintf_s(stderr, L"PdhAddCounter %s failed with 0x%x.\n", COUNTER_PATH_DISK_READ_ALL, status);
- ret = EXIT_FAILURE;
- goto cleanup;
- }
- if(status = PdhAddCounter(hQuery, COUNTER_PATH_DISK_WRITE_ALL, 0, &hCounterDiskWrite))
- {
- fwprintf_s(stderr, L"PdhAddCounter %s failed with 0x%x.\n", COUNTER_PATH_DISK_WRITE_ALL, status);
- ret = EXIT_FAILURE;
- goto cleanup;
- }
- if(status = PdhCollectQueryData(hQuery))
- {
- fwprintf_s(stderr, L"PdhCollectQueryData() failed with 0x%x.\n", status);
- ret = EXIT_FAILURE;
- goto cleanup;
- }
- // Read and aggregate counters
- status = ReadTotalCounter(hCounterNetRead, netRead);
- if(ERROR_SUCCESS != status)
- {
- fwprintf_s(stderr, L"ReadTotalCounter(Network Read): Error 0x%x.\n", status);
- ret = EXIT_FAILURE;
- }
- status = ReadTotalCounter(hCounterNetWrite, netWrite);
- if(ERROR_SUCCESS != status)
- {
- fwprintf_s(stderr, L"ReadTotalCounter(Network Write): Error 0x%x.\n", status);
- ret = EXIT_FAILURE;
- }
- status = ReadTotalCounter(hCounterDiskRead, diskRead);
- if(ERROR_SUCCESS != status)
- {
- fwprintf_s(stderr, L"ReadTotalCounter(Disk Read): Error 0x%x.\n", status);
- ret = EXIT_FAILURE;
- }
- status = ReadTotalCounter(hCounterDiskWrite, diskWrite);
- if(ERROR_SUCCESS != status)
- {
- fwprintf_s(stderr, L"ReadTotalCounter(Disk Write): Error 0x%x.\n", status);
- ret = EXIT_FAILURE;
- }
- cleanup:
- if (hQuery)
- {
- status = PdhCloseQuery(hQuery);
- }
- return ret;
- }
- PDH_STATUS ReadTotalCounter(PDH_HCOUNTER hCounter, LONGLONG* ret)
- {
- PDH_STATUS status = ERROR_SUCCESS;
- DWORD i = 0;
- DWORD dwBufferSize = 0;
- DWORD dwItemCount = 0;
- PDH_RAW_COUNTER_ITEM *pItems = NULL;
- // Initialize output
- *ret = 0;
- // Get the required size of the pItems buffer
- status = PdhGetRawCounterArray(hCounter, &dwBufferSize, &dwItemCount, NULL);
- if (PDH_MORE_DATA == status)
- {
- pItems = (PDH_RAW_COUNTER_ITEM *) malloc(dwBufferSize);
- if (pItems)
- {
- // Actually query the counter
- status = PdhGetRawCounterArray(hCounter, &dwBufferSize, &dwItemCount, pItems);
- if (ERROR_SUCCESS == status) {
- for (i = 0; i < dwItemCount; i++) {
- if (wcscmp(L"_Total", pItems[i].szName) == 0) {
- *ret = pItems[i].RawValue.FirstValue;
- break;
- } else {
- *ret += pItems[i].RawValue.FirstValue;
- }
- }
- } else {
- *ret = -1;
- goto cleanup;
- }
- // Reset structures
- free(pItems);
- pItems = NULL;
- dwBufferSize = dwItemCount = 0;
- } else {
- *ret = -1;
- status = PDH_NO_DATA;
- goto cleanup;
- }
- } else {
- *ret = -1;
- goto cleanup;
- }
- cleanup:
- if (pItems) {
- free(pItems);
- }
- return status;
- }
|