Hi
I want to get the system uptime. If i use GetTickCount will not work if the system has been on more then 47,7 days. How can i do?
Posted on 2005-10-08 16:16:35 by lilljocke
From the PlatformSDK:

To obtain the time elapsed since the computer was started, retrieve the System Up Time counter in the performance data in the registry key HKEY_PERFORMANCE_DATA. The value returned is an 8-byte value. For more information, see Performance Monitoring.


Iirc that is NT-specific, but... a 9x box that has been on more than ~47 days without crashing? ;)
Posted on 2005-10-08 16:43:23 by f0dder
I don't understand how to access the key?
How about use GetLocalTime and count how many days?
Posted on 2005-10-08 16:55:58 by lilljocke
use rdtsc instruction. just use sleep(1000) to calculate how many clocks/sec then divide the result of rdtsc by the clock/sec and you have your uptime in seconds.
Posted on 2005-10-08 19:14:33 by Qages
Qages, does that take into account power-saving technologies that reduces clock frequency?

Really, just look up "Performance Monitoring" in the PlatformSDK :)
Posted on 2005-10-08 19:27:08 by f0dder
If i use RDTSC would that work for any uptime or is it limited? How do i get the clock/sec with Sleep,1000 i just reccive 00000000 in eax efter Sleep,1000
Posted on 2005-10-08 20:25:33 by lilljocke
You call RDTSC before the sleep, save edx:eax, and call it again after. This is "moderately accurate". But again, there's problems if you have a machine that reduces it's clock frequency for power saving.

You can start browsing here: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/perfmon/base/using_performance_monitoring.asp - performance monitoring is a pretty large subject though.
Posted on 2005-10-08 20:54:19 by f0dder
I don't understand how you mean

rdtsc
push eax
push edx
rdtsc
        invoke Sleep,1000

is this correct?
what do i do then
Posted on 2005-10-08 21:19:04 by lilljocke
You don't do it that way, period.

Let me try whipping up a sample using the PDH interface... it's no joy to work with, but at least it ought to be reliable once done.
Posted on 2005-10-08 21:54:47 by f0dder
rdtsc           ;;get system uptime in processor ticks EDX:EAX
mov ebx,eax ;save
mov esi,edx
push 0
push 1000
call ;wait 1second
rdtsc            ;get the new time stamp
mov ecx, eax ;save
mov edi,edx
sub ecx,ebx   ;64bit subtract in 32bit land
sbb edi,esi
div ecx          ;get uptime in seconds
;;;eax = number of seconds the system has been up
xor edx,edx
mov ecx,60
div ecx
;;;eax = number of minutes ;;;edx = seconds

Another method could be getting the last modified file time of a boot file/log and then subtracting that from the current time.
0.log
passwd.log
wiaservc.log
wbemprox.log
windowsupdate.log
are all modified at start up.

Neither of these methods are perfect BUT they'll work.
Method one has the added bunus of giving you the current hz of the processor
If you don't want the SleepEx to slow your app down you should put method one in a seperate thread.
Posted on 2005-10-08 22:05:06 by r22
Here's the proper way to do it for NT4 or better systems... for win9x, it should be fine using the GetTickCount approach, at least I haven't seen a 9x box that could stay up that long :)

Stay away from the hacky rdtsc methods, they will introduce a 1sec delay in your app, are unreliable on power-saving enabled processors, etc.

The code is in C, but would be straightforward to translate to assembly.
Attachments:
Posted on 2005-10-08 22:22:38 by f0dder
Even if a Win9x box could last that long, only properly patched ones could actually cope with the counter rollover. See the old article- Windows may crash after 49.7 days.

lilljocke, This is a pretty horrible solution, but if your program ran in the background it could monitor the TickCount rollover and compensate for it itself.
Posted on 2005-10-09 07:22:15 by Eóin
Well i use Win NT systems in my home so it is OK if it not working with 9x. I'm trying to convert that code C++ f0dder sent me but i'm stuck with it. It seems like MASM doesn't know the structure PDH_FMT_COUNTERVALUE. The program showed me some error in my XP but not on my server with Windows Server 2003 Enterprise Edittion. I show you how far i have come with the conversion from the code.
Attachments:
Posted on 2005-10-09 08:37:12 by lilljocke
Another method is one read of QueryPerfomanceCounter. QPC/QPF = sys uptime . Rollover should not present a problem.
Posted on 2005-10-09 11:37:09 by alpha

I'm trying to convert that code C++ f0dder sent me but i'm stuck with it. It seems like MASM doesn't know the structure PDH_FMT_COUNTERVALUE.

Then there's some manual conversion work to do :)


The program showed me some error in my XP but not on my server with Windows Server 2003 Enterprise Edittion.

Hm, that's pretty interesting! Did my .exe show the error on XP? I'm running XP SP2 myself. I wonder if the PDH stuff requires administrative privileges or something like that?
Posted on 2005-10-09 12:16:03 by f0dder
So how do i convert it to asm code then? i can't do it myself becouse i'm stuck
Posted on 2005-10-09 13:49:16 by lilljocke
also...QPC/QPF works with all win32 versions from W32s
Posted on 2005-10-09 14:08:04 by alpha
I have never heard about QPC/QPF can you explain?
Posted on 2005-10-09 14:11:25 by lilljocke
See my previous post in this thread. QPF is QueryPerformanceFrequency.
Posted on 2005-10-09 14:15:30 by alpha
I don't understand what QueryPerformanceFrequency does and how do i use it. I don't understand none of these APIs you talking about. I checked QueryPerformanceFrequency on Msdn but i don't understand how i should use it.
Posted on 2005-10-09 14:21:35 by lilljocke