// UpTime.cpp : Defines the entry point for the console application.
#include "stdafx.h"
/* define some C99 types for windows */
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
typedef unsigned __int8 uint8_t;
typedef __int64 int64_t;
/*static*/ char msgstr[21];
#define KEY_SYSTEM L"2"
#define IDX_UPTIME 674
static void get_boottime(ULARGE_INTEGER *boottime, ULARGE_INTEGER *nowtime) {
BYTE pbuf[4096];
PPERF_DATA_BLOCK ppdb = (PPERF_DATA_BLOCK) pbuf;
DWORD psz = sizeof(pbuf);
PPERF_OBJECT_TYPE ppot;
PPERF_COUNTER_DEFINITION ppcd;
PPERF_COUNTER_BLOCK ppcb;
DWORD i;
memset(pbuf, 0, psz);
nowtime->QuadPart = boottime->QuadPart = 0; /* 0 = error */
/* get current 64-bit boottime in 100ns units */
RegQueryValueExW(HKEY_PERFORMANCE_DATA, KEY_SYSTEM, NULL, NULL, pbuf, &psz);
RegCloseKey(HKEY_PERFORMANCE_DATA);
if(memcmp(pbuf, L"PERF", 8)) {
/* PERF_DATA_BLOCK signature not present */
return;
}
/* parse returned performance data */
ppot = (PPERF_OBJECT_TYPE) &pbuf[ppdb->HeaderLength];
ppcd = (PPERF_COUNTER_DEFINITION) &pbuf[ppdb->HeaderLength + ppot->HeaderLength];
ppcb = (PPERF_COUNTER_BLOCK) &(((uint8_t *)ppot)[ppot->DefinitionLength]);
nowtime->QuadPart = ppdb->PerfTime100nSec.QuadPart;
/* get uptime and processor queue length */
for (i = 0; i < ppot->NumCounters; i++) {
if (ppcd->CounterNameTitleIndex == IDX_UPTIME) {
boottime->QuadPart = (int64_t) *(uint64_t *) &(((uint8_t *)ppcb)[ppcd->CounterOffset]);
}
ppcd++;
}
}
int main() {
ULARGE_INTEGER bt, nt, ut;
uint32_t days;
SYSTEMTIME ust;
get_boottime(&bt, &nt);
ut.QuadPart = nt.QuadPart - bt.QuadPart;
FileTimeToSystemTime((FILETIME *) &ut, &ust);
ut.QuadPart /= 864000000000;
days = (uint32_t) ut.QuadPart;
if(days > 1) {
sprintf(msgstr, "\r\n %d days, %02d:%02d:%02d\r\n", days, ust.wHour, ust.wMinute, ust.wSecond);
}else if(days == 1) {
sprintf(msgstr, "\r\n 1 day, %02d:%02d:%02d\r\n", ust.wHour, ust.wMinute, ust.wSecond);
}else{
sprintf(msgstr, "\r\n 0 days, %02d:%02d:%02d\r\n", ust.wHour, ust.wMinute, ust.wSecond);
}
printf(msgstr);
return 0;
}