windows-nt/Source/XPSP1/NT/net/snmp/common/dll/uptime.c

230 lines
6.1 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1992-1997 Microsoft Corporation
Module Name:
uptime.c
Abstract:
Contains routines to calculate sysUpTime.
SnmpSvcInitUptime
SnmpSvcGetUptime
SnmpSvcGetUptimeFromTime
Environment:
User Mode - Win32
Revision History:
--*/
///////////////////////////////////////////////////////////////////////////////
// //
// Include files //
// //
///////////////////////////////////////////////////////////////////////////////
#include <nt.h>
#include <windef.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <snmp.h>
#include <snmputil.h>
#include <ntfuncs.h>
///////////////////////////////////////////////////////////////////////////////
// //
// Global Variables //
// //
///////////////////////////////////////////////////////////////////////////////
DWORD g_dwUpTimeReference = 0;
LONGLONG g_llUpTimeReference = 0;
///////////////////////////////////////////////////////////////////////////////
// //
// Private Definitions //
// //
///////////////////////////////////////////////////////////////////////////////
#define INVALID_UPTIME 0xFFFFFFFF
///////////////////////////////////////////////////////////////////////////////
// //
// Private Procedures //
// //
///////////////////////////////////////////////////////////////////////////////
DWORD
SNMP_FUNC_TYPE
SnmpSvcInitUptime(
)
/*++
Routine Description:
Initializes sysUpTime reference for SNMP process.
Arguments:
None.
Return Values:
Returns sysUpTime reference to pass to subagents.
--*/
{
NTSTATUS NtStatus;
SYSTEM_TIMEOFDAY_INFORMATION TimeOfDay;
// obtain reference the outdated way
g_dwUpTimeReference = GetCurrentTime();
// query time in spiffy new precise manner
NtStatus = NtQuerySystemInformation(
SystemTimeOfDayInformation,
&TimeOfDay,
sizeof(SYSTEM_TIMEOFDAY_INFORMATION),
NULL
);
// validate return code
if (NT_SUCCESS(NtStatus)) {
// initialize higher precision startup time
g_llUpTimeReference = TimeOfDay.CurrentTime.QuadPart;
}
//
// The algorithm for subagents to calculate sysUpTime
// is based on GetCurrentTime() which returns the time
// in milliseconds and therefore wraps every 49.71 days.
// RFC1213 specifies that sysUpTime is to be returned in
// centaseconds but we cannot break existing subagents.
// The old value is returned to the master agent here
// but newer subagents should use SnmpUtilGetUpTime.
//
return g_dwUpTimeReference;
}
///////////////////////////////////////////////////////////////////////////////
// //
// Public Procedures //
// //
///////////////////////////////////////////////////////////////////////////////
DWORD
SNMP_FUNC_TYPE
SnmpSvcGetUptime(
)
/*++
Routine Description:
Retrieves sysUpTime for SNMP process.
Arguments:
None.
Return Values:
Returns sysUpTime value for use by subagents.
--*/
{
DWORD dwUpTime = INVALID_UPTIME;
NTSTATUS NtStatus;
SYSTEM_TIMEOFDAY_INFORMATION TimeOfDay;
// query time in spiffy new precise manner
NtStatus = NtQuerySystemInformation(
SystemTimeOfDayInformation,
&TimeOfDay,
sizeof(SYSTEM_TIMEOFDAY_INFORMATION),
NULL
);
// validate return code
if (NT_SUCCESS(NtStatus)) {
LARGE_INTEGER liUpTime;
LARGE_INTEGER liUpTimeInCentaseconds;
// calculate difference from reference
liUpTime.QuadPart = TimeOfDay.CurrentTime.QuadPart -
g_llUpTimeReference;
// convert 100ns units (10^-7) into centasecond units (10^-2)
liUpTimeInCentaseconds = RtlExtendedLargeIntegerDivide(
liUpTime,
100000,
NULL
);
// convert large integer to dword value
dwUpTime = (DWORD)(LONGLONG)liUpTimeInCentaseconds.QuadPart;
} else if (g_dwUpTimeReference != 0) {
// calculate difference from reference
dwUpTime = (GetCurrentTime() - g_dwUpTimeReference) / 10;
}
return dwUpTime;
}
DWORD
SNMP_FUNC_TYPE
SnmpSvcGetUptimeFromTime(
DWORD dwUpTime
)
/*++
Routine Description:
Retrieves sysUpTime value for a given tick count.
Arguments:
dwUpTime - stack uptime (in centaseconds) to convert to sysUpTime
Return Values:
Returns sysUpTime value for use by subagents.
--*/
{
DWORD dwUpTimeReferenceInCentaseconds;
// convert 100ns units (10^-7) into centasecond units (10^-2)
dwUpTimeReferenceInCentaseconds = (DWORD)(g_llUpTimeReference / 100000);
if (dwUpTime < dwUpTimeReferenceInCentaseconds) {
return 0;
}
// calculate difference from reference
return dwUpTime - dwUpTimeReferenceInCentaseconds;
}