Jump-start your project by learning from devs who
write Windows drivers and file systems every day.
Take an OSR seminar!

OSR is Hiring! Click here to find out more.

Upcoming OSR Seminars:
Kernel Debugging & Crash Analysis for Windows Lab, Santa Clara, CA 9-13 September, 2013
Upcoming OSR Seminars:
Windows Internals & Software Drivers Lab, Santa Clara, CA 16-20 September, 2013
Writing WDF Drivers for Windows Lab, Boston/Waltham, MA 7-11 October, 2013
Developing File Systems for Windows, Seattle, WA 5-8 November, 2013


Go Back   OSR Online Lists > ntdev
Welcome, Guest
You must login to post to this list
  Message 1 of 6  
06 Apr 01 11:51
ntdev member 610
xxxxxx@vertical.com
Join Date:
Posts To This List: 139
Last Boot Time in Registry or API?

I want to find out the last time the system booted. I'm not particular on the time exactly. I just want to get some approximate time that the operating system had just been started, or even, perhaps, the last time it was shut down, or as a last resort, the amount of time that it's been up. I just want some reference to a time period before any drivers or services could have started. (The reason for this is so that I can rename my log files, which were created during the previous boot, to something with a meaningful timestamp -- however, I want all of my drivers and services to agree on this name, so just getting the current time does not cut it.) I expected that I'd find it in the Registry or through some API, but I was unable to find it. (And yes, I know that I could parse the Event Log, but that's far more trouble than it's worth.) Any ideas? I'm sure it must exist! Thanks! --- You are currently subscribed to ntdev as: $subst('Recip.EmailAddr') To unsubscribe send a blank email to leave-ntdev-$subst('Recip.MemberIDChar')@lists.osr.com
  Message 2 of 6  
06 Apr 01 12:04
Rob Linegar
xxxxxx@des.co.uk
Join Date:
Posts To This List: 111
RE: Last Boot Time in Registry or API?

DWORD GetTickCount(VOID); From the MSDN. "The return value is the number of milliseconds that have elapsed since the system was started" Rob Linegar Software Engineer Data Encryption Systems Limited -----Original Message----- From: Taed Nelson [mailto:xxxxx@vertical.com] Sent: 06 April 2001 16:48 To: NT Developers Interest List Subject: [ntdev] Last Boot Time in Registry or API? I want to find out the last time the system booted. I'm not particular on the time exactly. I just want to get some approximate time that the operating system had just been started, or even, perhaps, the last time it was shut down, or as a last resort, the amount of time that it's been up. I just want some reference to a time period before any drivers or services could have started. (The reason for this is so that I can rename my log files, which were created during the previous boot, to something with a meaningful timestamp -- however, I want all of my drivers and services to agree on this name, so just getting the current time does not cut it.) I expected that I'd find it in the Registry or through some API, but I was unable to find it. (And yes, I know that I could parse the Event Log, but that's far more trouble than it's worth.) Any ideas? I'm sure it must exist! Thanks! --- You are currently subscribed to ntdev as: xxxxx@des.co.uk To unsubscribe send a blank email to leave-ntdev-$subst('Recip.MemberIDChar')@lists.osr.com --- You are currently subscribed to ntdev as: $subst('Recip.EmailAddr') To unsubscribe send a blank email to leave-ntdev-$subst('Recip.MemberIDChar')@lists.osr.com
  Message 3 of 6  
06 Apr 01 13:54
Danilo Almeida
xxxxxx@MIT.EDU
Join Date:
Posts To This List: 58
RE: Last Boot Time in Registry or API?

Taed, Rob's answer answer does not really tell you a way to figure a boot time that is consistent from any driver. Using GetTicCount() and rounding your computation to the nearest minute would help, but you might still get things that were off by a minute if you were near the rounding cutoff. You could couple something like GetTickCount() with some shared memory and synchronization. A simple way would be to have each driver to try to create a named event (manual reset). The first driver to do so (i.e., if the event did not already exist) would then create a shared memory region, set the start time in the shared memory based on the current time minus the system uptime, and signal the event. If the event already existed, the driver would just wait on it. Then it would open the shared memory and check the time value. [Note: there are some degenerate cases where this would not work -- most notably if driver1 starts then stops and then driver2 starts then stops -- you will likely get different times in such a case.] You should also be aware that GetTickCount() is only valid if the system has been up for less than about 47 days. If the drivers could be started after 47 days of system uptime, GetTickCount() would not be appropriate. For more than 47 days, you can use performance counters. Below is some test performance counter code to get you started. It has been tested on Windows 2000. Note that there is a difference between the awake time and the elapsed time of the system/idle processed if the system is hibernated. That's why I output both. The process uptimes were just for more research. You can just remove that. In general, however, the event log is the only way I know to get a consistent system start time w/o creating your own canonical start time source. Enjoy, - Danilo P.S.: You'll need to link with psapi.lib and pdh.lib --------------------------- #define WIN32_LEAN_AND_MEAN 1 #include <windows.h> #include <winperf.h> #include <malloc.h> #include <stdio.h> #include <stdlib.h> #include <tchar.h> #include <pdh.h> #include <psapi.h> void print_time( char* prefix, __int64 t ) { __int64 secs = t % 60; t /= 60; __int64 mins = t % 60; t /= 60; __int64 hours = t % 24; t /= 24; __int64 days = t; printf("%s" "%3I64d days, %2I64d hours, %2I64d minutes, %2I64d seconds\n", prefix, days, hours, mins, secs); } PDH_STATUS get_number_cv( char* counter, DWORD *pdwType, PDH_FMT_COUNTERVALUE *pcv ) { PDH_STATUS pdhStatus = ERROR_SUCCESS; HQUERY hQuery = 0; HCOUNTER hCounter = 0; pdhStatus = PdhOpenQuery(0, 0, &hQuery); if (pdhStatus != ERROR_SUCCESS) { fprintf(stderr, "Error while opening query\n"); goto cleanup; } pdhStatus = PdhAddCounter(hQuery, counter, 0, &hCounter); if (pdhStatus) { fprintf(stderr, "Error while adding counter %s to query\n", counter); goto cleanup; } pdhStatus = PdhCollectQueryData(hQuery); if (pdhStatus) { fprintf(stderr, "Error collecting query data\n"); goto cleanup; } pdhStatus = PdhGetFormattedCounterValue(hCounter, PDH_FMT_LARGE | PDH_FMT_NOSCALE, pdwType, pcv); if (pdhStatus) { fprintf(stderr, "Error formatting counter value\n"); goto cleanup; } // We can close the query since we do not need to refer to any of the // string members. cleanup: if (hQuery) PdhCloseQuery(hQuery); return pdhStatus; } PDH_STATUS get_and_print_time_cv( char* prefix, char* path ) { PDH_STATUS pdhStatus = ERROR_SUCCESS; DWORD dwType = 0; PDH_FMT_COUNTERVALUE cv; pdhStatus = get_number_cv(path, &dwType, &cv); if (pdhStatus) return pdhStatus; //printf("Type: 0x%08x, Value: 0x%016I64x\n", dwType, cv.largeValue); print_time(prefix, cv.largeValue); return 0; } __int64 filetime_to_seconds( FILETIME ft ) { return *((__int64*)&ft) / ( 1000 * 1000 * 1000 / 100 ); } void do_processes() { int i; DWORD cb = 0; BOOL ok = TRUE; DWORD chunk = 5 * sizeof(DWORD); DWORD size = chunk; DWORD* ap = (DWORD*) malloc(size); while ((ok = EnumProcesses(ap, size, &cb)) && (size < (sizeof(DWORD) + cb))) { cb = 0; free(ap); size += chunk; ap = (DWORD*)malloc(size); } if (!ok) { printf("Error enumerating processes (%u)\n", GetLastError()); goto cleanup; } for (i = 0; i < (cb / sizeof(DWORD)); i++) { DWORD p = ap[i]; char label[64]; _snprintf(label, sizeof(label) - 1, "Up Time (%6u): ", p); HANDLE hp = OpenProcess(STANDARD_RIGHTS_READ | PROCESS_QUERY_INFORMATION, FALSE, p); if (!hp || (hp == INVALID_HANDLE_VALUE)) { printf("%s could not open process (error %u)\n", label, GetLastError()); continue; } fflush(stdout); FILETIME ft; FILETIME ft1; FILETIME ft2; FILETIME ft3; if (GetProcessTimes(hp, &ft, &ft1, &ft2, &ft2)) { FILETIME sft; GetSystemTimeAsFileTime(&sft); __int64 st = filetime_to_seconds(sft); __int64 pt = filetime_to_seconds(ft); if (pt) { print_time(label, st - pt); } else { printf("%s no creation time\n", label); } } else { printf("%s could not get times (error %u)\n", label, GetLastError()); } } cleanup: if (ap) free(ap); } void usage( char* progname ) { printf("usage: %s [-p]\n" " -p show process times\n", progname); exit(1); } int main( int argc, char* argv[] ) { PDH_STATUS pdhStatus = ERROR_SUCCESS; BOOL bProc = FALSE; if (argc > 2) usage(argv[0]); if (argc > 1) { if (!strcmp(argv[1], "-p")) { bProc = TRUE; } else { usage(argv[0]); } } pdhStatus = get_and_print_time_cv(" Awake Time: ", "\\System\\System Up Time"); if (pdhStatus) exit(1); pdhStatus = get_and_print_time_cv("Elapsed Time: ", "\\Process(System)\\Elapsed Time"); if (pdhStatus) exit(1); pdhStatus = get_and_print_time_cv("Elapsed Time: ", "\\Process(Idle)\\Elapsed Time"); if (pdhStatus) exit(1); if (bProc) do_processes(); return 0; } > -----Original Message----- > From: xxxxx@lists.osr.com > [mailto:xxxxx@lists.osr.com]On Behalf Of xxxxx@des.co.uk > Sent: Friday, April 06, 2001 12:01 PM > To: NT Developers Interest List > Subject: [ntdev] RE: Last Boot Time in Registry or API? > > > <...excess quoted lines suppressed...> up. > > I just want some reference to a time period before any drivers or > services could have started. (The reason for this is so that I can > rename my log files, which were created during the previous boot, to > something with a meaningful timestamp -- however, I want all of my > drivers and services to agree on this name, so just getting the current > time does not cut it.) > > I expected that I'd find it in the Registry or through some API, but I > was unable to find it. --- You are currently subscribed to ntdev as: $subst('Recip.EmailAddr') To unsubscribe send a blank email to leave-ntdev-$subst('Recip.MemberIDChar')@lists.osr.com
  Message 4 of 6  
06 Apr 01 13:55
ntdev member 3954
xxxxxx@aalayance.com
Join Date:
Posts To This List: 101
Re: Last Boot Time in Registry or API?

Hi , Check the following keys. Value type is Binary : 1) HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Windows\ShutdownTime 2) HKEY_LOCAL_MACHINE\SYSTEM\ControlSet002\Control\Windows\ShutdownTime 3) HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows\ShutdownTime Hope this helps, Regards, Satish K.S ----- Original Message ----- From: "Taed Nelson" <xxxxx@vertical.com> To: "NT Developers Interest List" <xxxxx@lists.osr.com> Sent: Friday, April 06, 2001 9:18 PM Subject: [ntdev] Last Boot Time in Registry or API? > I want to find out the last time the system booted. I'm not particular on > the time exactly. I just want to get some approximate time that the > operating system had just been started, or even, perhaps, the last time it > was shut down, or as a last resort, the amount of time that it's been up. > > I just want some reference to a time period before any drivers or services > could have started. (The reason for this is so that I can rename my log > files, which were created during the previous boot, to something with a <...excess quoted lines suppressed...> --- You are currently subscribed to ntdev as: $subst('Recip.EmailAddr') To unsubscribe send a blank email to leave-ntdev-$subst('Recip.MemberIDChar')@lists.osr.com
  Message 5 of 6  
06 Apr 01 14:18
ntdev member 4924
xxxxxx@ntrealtime.com
Join Date:
Posts To This List: 14
Re: Last Boot Time in Registry or API?

Hi: At any time in your driver, get current time and subtract from it GetTickCount() properly scaled. Then store it in the registry. Next time you boot, it will be there for you.. Use it or save it before you replace it with the new value. George At 08:48 AM 4/6/01 -0700, you wrote: >I want to find out the last time the system booted. I'm not particular on >the time exactly. I just want to get some approximate time that the >operating system had just been started, or even, perhaps, the last time it >was shut down, or as a last resort, the amount of time that it's been up. > >I just want some reference to a time period before any drivers or services >could have started. (The reason for this is so that I can rename my log >files, which were created during the previous boot, to something with a >meaningful timestamp -- however, I want all of my drivers and services to >agree on this name, so just getting the current time does not cut it.) <...excess quoted lines suppressed...> --- You are currently subscribed to ntdev as: $subst('Recip.EmailAddr') To unsubscribe send a blank email to leave-ntdev-$subst('Recip.MemberIDChar')@lists.osr.com --
  Message 6 of 6  
07 Apr 01 00:22
ntdev member 610
xxxxxx@vertical.com
Join Date:
Posts To This List: 139
Re: Last Boot Time in Registry or API?

> HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows\ShutdownTime Thanks! That is PERFECT! I did some quick testing, and it even seems to handle the case where I just shut off the machine without warning. Of course, I don't expect it to be accurate, but I don't care for my purposes. I suspect this key was added in NT SP 4 as part of the "uptime" enhancements? If so, it should be updated every 5 minutes (although that can be disabled if you desire to have the hard drive go into sleep mode). (BTW, if you haven't used the UPTIME tool, I suggest you download it from Microsoft; it's very useful for presenting a nice summary (and statistics) of the information in the Event Log.) --- You are currently subscribed to ntdev as: $subst('Recip.EmailAddr') To unsubscribe send a blank email to leave-ntdev-$subst('Recip.MemberIDChar')@lists.osr.com
Posting Rules  
You may not post new threads
You may not post replies
You may not post attachments
You must login to OSR Online AND be a member of the ntdev list to be able to post.

All times are GMT -5. The time now is 00:46.


Copyright ©2012, OSR Open Systems Resources, Inc.
Based on vBulletin Copyright ©2000 - 2005, Jelsoft Enterprises Ltd.
Modified under license