Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

229 lines
6.3 KiB

  1. /*++
  2. Copyright (c) 1992-1997 Microsoft Corporation
  3. Module Name:
  4. uptime.c
  5. Abstract:
  6. Contains routines to calculate sysUpTime.
  7. SnmpSvcInitUptime
  8. SnmpSvcGetUptime
  9. SnmpSvcGetUptimeFromTime
  10. Environment:
  11. User Mode - Win32
  12. Revision History:
  13. --*/
  14. ///////////////////////////////////////////////////////////////////////////////
  15. // //
  16. // Include files //
  17. // //
  18. ///////////////////////////////////////////////////////////////////////////////
  19. #include <nt.h>
  20. #include <windef.h>
  21. #include <ntrtl.h>
  22. #include <nturtl.h>
  23. #include <windows.h>
  24. #include <snmp.h>
  25. #include <snmputil.h>
  26. #include <ntfuncs.h>
  27. ///////////////////////////////////////////////////////////////////////////////
  28. // //
  29. // Global Variables //
  30. // //
  31. ///////////////////////////////////////////////////////////////////////////////
  32. DWORD g_dwUpTimeReference = 0;
  33. LONGLONG g_llUpTimeReference = 0;
  34. ///////////////////////////////////////////////////////////////////////////////
  35. // //
  36. // Private Definitions //
  37. // //
  38. ///////////////////////////////////////////////////////////////////////////////
  39. #define INVALID_UPTIME 0xFFFFFFFF
  40. ///////////////////////////////////////////////////////////////////////////////
  41. // //
  42. // Private Procedures //
  43. // //
  44. ///////////////////////////////////////////////////////////////////////////////
  45. DWORD
  46. SNMP_FUNC_TYPE
  47. SnmpSvcInitUptime(
  48. )
  49. /*++
  50. Routine Description:
  51. Initializes sysUpTime reference for SNMP process.
  52. Arguments:
  53. None.
  54. Return Values:
  55. Returns sysUpTime reference to pass to subagents.
  56. --*/
  57. {
  58. NTSTATUS NtStatus;
  59. SYSTEM_TIMEOFDAY_INFORMATION TimeOfDay;
  60. // obtain reference the outdated way
  61. g_dwUpTimeReference = GetCurrentTime();
  62. // query time in spiffy new precise manner
  63. NtStatus = NtQuerySystemInformation(
  64. SystemTimeOfDayInformation,
  65. &TimeOfDay,
  66. sizeof(SYSTEM_TIMEOFDAY_INFORMATION),
  67. NULL
  68. );
  69. // validate return code
  70. if (NT_SUCCESS(NtStatus)) {
  71. // initialize higher precision startup time
  72. g_llUpTimeReference = TimeOfDay.CurrentTime.QuadPart;
  73. }
  74. //
  75. // The algorithm for subagents to calculate sysUpTime
  76. // is based on GetCurrentTime() which returns the time
  77. // in milliseconds and therefore wraps every 49.71 days.
  78. // RFC1213 specifies that sysUpTime is to be returned in
  79. // centaseconds but we cannot break existing subagents.
  80. // The old value is returned to the master agent here
  81. // but newer subagents should use SnmpUtilGetUpTime.
  82. //
  83. return g_dwUpTimeReference;
  84. }
  85. ///////////////////////////////////////////////////////////////////////////////
  86. // //
  87. // Public Procedures //
  88. // //
  89. ///////////////////////////////////////////////////////////////////////////////
  90. DWORD
  91. SNMP_FUNC_TYPE
  92. SnmpSvcGetUptime(
  93. )
  94. /*++
  95. Routine Description:
  96. Retrieves sysUpTime for SNMP process.
  97. Arguments:
  98. None.
  99. Return Values:
  100. Returns sysUpTime value for use by subagents.
  101. --*/
  102. {
  103. DWORD dwUpTime = INVALID_UPTIME;
  104. NTSTATUS NtStatus;
  105. SYSTEM_TIMEOFDAY_INFORMATION TimeOfDay;
  106. // query time in spiffy new precise manner
  107. NtStatus = NtQuerySystemInformation(
  108. SystemTimeOfDayInformation,
  109. &TimeOfDay,
  110. sizeof(SYSTEM_TIMEOFDAY_INFORMATION),
  111. NULL
  112. );
  113. // validate return code
  114. if (NT_SUCCESS(NtStatus)) {
  115. LARGE_INTEGER liUpTime;
  116. LARGE_INTEGER liUpTimeInCentaseconds;
  117. // calculate difference from reference
  118. liUpTime.QuadPart = TimeOfDay.CurrentTime.QuadPart -
  119. g_llUpTimeReference;
  120. // convert 100ns units (10^-7) into centasecond units (10^-2)
  121. liUpTimeInCentaseconds = RtlExtendedLargeIntegerDivide(
  122. liUpTime,
  123. 100000,
  124. NULL
  125. );
  126. // convert large integer to dword value
  127. dwUpTime = (DWORD)(LONGLONG)liUpTimeInCentaseconds.QuadPart;
  128. } else if (g_dwUpTimeReference != 0) {
  129. // calculate difference from reference
  130. dwUpTime = (GetCurrentTime() - g_dwUpTimeReference) / 10;
  131. }
  132. return dwUpTime;
  133. }
  134. DWORD
  135. SNMP_FUNC_TYPE
  136. SnmpSvcGetUptimeFromTime(
  137. DWORD dwUpTime
  138. )
  139. /*++
  140. Routine Description:
  141. Retrieves sysUpTime value for a given tick count.
  142. Arguments:
  143. dwUpTime - stack uptime (in centaseconds) to convert to sysUpTime
  144. Return Values:
  145. Returns sysUpTime value for use by subagents.
  146. --*/
  147. {
  148. DWORD dwUpTimeReferenceInCentaseconds;
  149. // convert 100ns units (10^-7) into centasecond units (10^-2)
  150. dwUpTimeReferenceInCentaseconds = (DWORD)(g_llUpTimeReference / 100000);
  151. if (dwUpTime < dwUpTimeReferenceInCentaseconds) {
  152. return 0;
  153. }
  154. // calculate difference from reference
  155. return dwUpTime - dwUpTimeReferenceInCentaseconds;
  156. }