大悟还俗

邮箱 key_ok@qq.com 我的收集 http://pan.baidu.com/share/home?uk=1177427271
posts - 236, comments - 8, trackbacks - 0, articles - 0
  新随笔  :: 联系 :: 订阅 订阅  :: 管理

一个可以再WIN2000及以上操作系统使用的GetTickCount64

Posted on 2014-01-06 00:15  大悟还俗  阅读(...)  评论(... 编辑 收藏
以后尽量用Delphi/C++双代码写.

GetTickCount返回值是整数,这样的话最多49天多就会复位重新从0开始.Vista以后提供了GetTickCount64这个函数,但是WindowsXP还是主流.在项目中为了处理这个,自己实现了一套办法.这个GetTickCount和真正的额GetTickCount相比会恒定的相差800毫秒左右.不过这个不影响使用.获取开机时间这800毫秒完全可以忽略.计算时间差的话就和GetTickCount是一样的了.

 

Delphi版XE下编译通过.

 

type
   _SYSTEM_INFORMATION_CLASS = (
     SystemBasicInformation,
     SystemProcessorInformation,
     SystemPerformanceInformation,
     SystemTimeOfDayInformation,
     SystemNotImplemented1,
     SystemProcessesAndThreadsInformation,
     SystemCallCounts,
     SystemConfigurationInformation,
     SystemProcessorTimes,
     SystemGlobalFlag,
     SystemNotImplemented2,
     SystemModuleInformation,
     SystemLockInformation,
     SystemNotImplemented3,
     SystemNotImplemented4,
     SystemNotImplemented5,
     SystemHandleInformation,
     SystemObjectInformation,
     SystemPagefileInformation,
     SystemInstructionEmulationCounts,
     SystemInvalidInfoClass1,
     SystemCacheInformation,
     SystemPoolTagInformation,
     SystemProcessorStatistics,
     SystemDpcInformation,
     SystemNotImplemented6,
     SystemLoadImage,
     SystemUnloadImage,
     SystemTimeAdjustment,
     SystemNotImplemented7,
     SystemNotImplemented8,
     SystemNotImplemented9,
     SystemCrashDumpInformation,
     SystemExceptionInformation,
     SystemCrashDumpStateInformation,
     SystemKernelDebuggerInformation,
     SystemContextSwitchInformation,
     SystemRegistryQuotaInformation,
     SystemLoadAndCallImage,
     SystemPrioritySeparation,
     SystemNotImplemented10,
     SystemNotImplemented11,
     SystemInvalidInfoClass2,
     SystemInvalidInfoClass3,
     SystemTimeZoneInformation,
     SystemLookasideInformation,
     SystemSetTimeSlipEvent,
     SystemCreateSession,
     SystemDeleteSession,
     SystemInvalidInfoClass4,
     SystemRangeStartInformation,
     SystemVerifierInformation,
     SystemAddVerifier,
     SystemSessionProcessesInformation);
   SYSTEM_INFORMATION_CLASS = _SYSTEM_INFORMATION_CLASS;
   TSystemInformationClass = SYSTEM_INFORMATION_CLASS;

   _SYSTEM_TIME_OF_DAY_INFORMATION = record // Information Class 3
     BootTime: LARGE_INTEGER;
     CurrentTime: LARGE_INTEGER;
     TimeZoneBias: LARGE_INTEGER;
     CurrentTimeZoneId: ULONG;
   end;
   SYSTEM_TIME_OF_DAY_INFORMATION = _SYSTEM_TIME_OF_DAY_INFORMATION;
   PSYSTEM_TIME_OF_DAY_INFORMATION = ^SYSTEM_TIME_OF_DAY_INFORMATION;



 function  NtQuerySystemInformation(
     SystemInformationClass : SYSTEM_INFORMATION_CLASS;
     SystemInformation : PVOID;
     SystemInformationLength : ULONG;
     ReturnLength : PULONG
   ): Integer; stdcall; external 'ntdll.dll';

 function  NtQuerySystemTime(
     var CurrentTime : LARGE_INTEGER
   ): Integer; stdcall; external 'ntdll.dll';


 function _GetTickCount64():Int64;
 var
   st : SYSTEM_TIME_OF_DAY_INFORMATION;
   r : ULONG;
   ct : LARGE_INTEGER;
 begin
   NtQuerySystemInformation(SystemTimeOfDayInformation,
                            @st,
                            SizeOf(SYSTEM_TIME_OF_DAY_INFORMATION),
                            @r);
   NtQuerySystemTime(ct);
   Result :=(ct.QuadPart-st.BootTime.QuadPart)div 10000;
 end;

 

VC版:

typedef ULONGLONG (WINAPI GetTickCount64Proc)(void);
 typedef ULONG (__stdcall * NTQUERYSYSTEMINFORMATION)(IN     /*SYSTEM_INFORMATION_CLASS*/int, IN OUT PVOID, INT    ULONG, OUT    PULONG OPTION);
 GetTickCount64Proc* VistaGetTickCount64 = (GetTickCount64Proc*)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "GetTickCount64");

 NTQUERYSYSTEMINFORMATION _NtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), ("NtQuerySystemInformation"));

 INT64 _GetTickCount64()
 {
     typedef struct _SYSTEM_TIME_OF_DAY_INFORMATION
     {
         LARGE_INTEGER BootTime;
         LARGE_INTEGER CurrentTime;
         LARGE_INTEGER TimeZoneBias;
         ULONG CurrentTimeZoneId;
     } SYSTEM_TIME_OF_DAY_INFORMATION, *PSYSTEM_TIME_OF_DAY_INFORMATION;
     //如果系统存在VistaGetTickCount64函数则调用系统的
    if (VistaGetTickCount64) 
         return VistaGetTickCount64();
     SYSTEM_TIME_OF_DAY_INFORMATION  st ={0};
     ULONG                           oSize = 0;
     if((NULL == _NtQuerySystemInformation)||0 !=(_NtQuerySystemInformation(3, &st, sizeof(st), &oSize))||
         (oSize!= sizeof(st)))
         return GetTickCount();
     return (st.CurrentTime.QuadPart - st.BootTime.QuadPart)/10000;
 }