/* $Id: uptime.c,v 1.10 2002/08/22 19:06:58 nlaredo Exp $ * ----------------------------------------------------------------------- * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * ----------------------------------------------------------------------- * * uptime.c -- Nathan Laredo */ #include #include /* define some C99 types for windows */ typedef unsigned __int32 uint32_t; typedef unsigned __int16 uint16_t; typedef unsigned __int64 uint64_t; typedef unsigned __int8 uint8_t; typedef __int32 int32_t; typedef __int16 int16_t; typedef __int64 int64_t; typedef __int8 int8_t; static char msgstr[4096]; static int users = 0; #define KEY_SYSTEM L"2" #define IDX_UPTIME 674 #define IDX_PROCQUEUE 44 static void get_boottime(ULARGE_INTEGER *boottime, ULARGE_INTEGER *nowtime, uint32_t *procqueue) { 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]); } if (ppcd->CounterNameTitleIndex == IDX_PROCQUEUE) { *procqueue = (int32_t) *(uint32_t *) &(((uint8_t *)ppcb)[ppcd->CounterOffset]); } ppcd++; } } static BOOL CALLBACK ewsproc(LPTSTR lpszWindowStation, LPARAM lParam) { users++; return TRUE; } static void uptime(void) { ULARGE_INTEGER bt, nt, ut; uint32_t procqueue, days; SYSTEMTIME bst, nst, ust; TCHAR btstr[128], ntstr[128], bdstr[128]; get_boottime(&bt, &nt, &procqueue); ut.QuadPart = nt.QuadPart - bt.QuadPart; FileTimeToSystemTime((FILETIME *) &bt, &bst); FileTimeToSystemTime((FILETIME *) &nt, &nst); FileTimeToSystemTime((FILETIME *) &ut, &ust); SystemTimeToTzSpecificLocalTime(NULL, &bst, &bst); SystemTimeToTzSpecificLocalTime(NULL, &nst, &nst); GetTimeFormat(LOCALE_USER_DEFAULT, LOCALE_USE_CP_ACP, &bst, NULL, btstr, sizeof(btstr)); GetTimeFormat(LOCALE_USER_DEFAULT, LOCALE_USE_CP_ACP, &nst, NULL, ntstr, sizeof(ntstr)); GetDateFormat(LOCALE_USER_DEFAULT, LOCALE_USE_CP_ACP, &bst, NULL, bdstr, sizeof(bdstr)); sprintf(msgstr, " %s up ", ntstr); ut.QuadPart /= 864000000000; days = (uint32_t) ut.QuadPart; if (days > 1) { sprintf(&msgstr[strlen(msgstr)], "%d days, ", days); } else if (days == 1) { sprintf(&msgstr[strlen(msgstr)], "1 day, "); } sprintf(&msgstr[strlen(msgstr)], "%02d:%02d:%02d, ", ust.wHour, ust.wMinute, ust.wSecond); sprintf(&msgstr[strlen(msgstr)], "%d user%s, ", users, users == 1 ? "" : "s"); sprintf(&msgstr[strlen(msgstr)], "boot %s %s, " "load: %d", bdstr, btstr, procqueue); printf(msgstr); } int main(int argc, char **argv) { int count = atoi(argv[argc - 1]); EnumWindowStations(ewsproc, 0); uptime(); printf("\r\n"); for (; count > 0; count--) { Sleep(1000); printf("\r"); uptime(); if (count == 1) { printf("\r\n"); } } return 0; } /* EOF */