⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 time.c

📁 不错的东西 请查看 WINCE OS
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
/*
 *        Core DLL filetime / systemtime code
 *
 *
 * Module Name:
 *
 *        time.c
 *
 * Abstract:
 *
 *        This file implements Core DLL system and file time functions
 *
 * Revision History:
 *
 */

#include <windows.h>
#include <memory.h>
#include <notify.h>

extern BOOL IsAPIReady(DWORD hAPI);
extern void WINAPI I_BatteryNotifyOfTimeChange(BOOL fForward, FILETIME *pftDelta);



#define WEEKDAY_OF_1601    1

#define IsLeapYear(Y) (!((Y)%4) && (((Y)%100) || !((Y)%400)))

#define NumberOfLeapYears(Y) ((Y)/4 - (Y)/100 + (Y)/400)

#define ElapsedYearsToDays(Y) ((Y)*365 + NumberOfLeapYears(Y))

#define MaxDaysInMonth(Y,M) (IsLeapYear(Y) ? \
    LeapYearDaysBeforeMonth[(M) + 1] - LeapYearDaysBeforeMonth[M] : \
    NormalYearDaysBeforeMonth[(M) + 1] - NormalYearDaysBeforeMonth[M])

const WORD LeapYearDaysBeforeMonth[13] = {
    0,                                 // January
    31,                                // February
    31+29,                             // March
    31+29+31,                          // April
    31+29+31+30,                       // May
    31+29+31+30+31,                    // June
    31+29+31+30+31+30,                 // July
    31+29+31+30+31+30+31,              // August
    31+29+31+30+31+30+31+31,           // September
    31+29+31+30+31+30+31+31+30,        // October
    31+29+31+30+31+30+31+31+30+31,     // November
    31+29+31+30+31+30+31+31+30+31+30,  // December
    31+29+31+30+31+30+31+31+30+31+30+31};

const WORD NormalYearDaysBeforeMonth[13] = {
    0,                                 // January
    31,                                // February
    31+28,                             // March
    31+28+31,                          // April
    31+28+31+30,                       // May
    31+28+31+30+31,                    // June
    31+28+31+30+31+30,                 // July
    31+28+31+30+31+30+31,              // August
    31+28+31+30+31+30+31+31,           // September
    31+28+31+30+31+30+31+31+30,        // October
    31+28+31+30+31+30+31+31+30+31,     // November
    31+28+31+30+31+30+31+31+30+31+30,  // December
    31+28+31+30+31+30+31+31+30+31+30+31};

const BYTE LeapYearDayToMonth[366] = {
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // January
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,        // February
     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,  // March
     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,     // April
     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,  // May
     5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,     // June
     6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,  // July
     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,  // August
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,     // September
     9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,  // October
    10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,     // November
    11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11}; // December

const BYTE NormalYearDayToMonth[365] = {
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // January
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,           // February
     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,  // March
     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,     // April
     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,  // May
     5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,     // June
     6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,  // July
     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,  // August
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,     // September
     9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,  // October
    10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,     // November
    11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11}; // December


#define TIME_CHANGE_CNT      (((volatile DWORD *)UserKInfo)[KINX_TIMECHANGECOUNT])

#define GetKeyHKLM(valname,keyname,lptype,data,lplen)   RegQueryValueExW(HKEY_LOCAL_MACHINE,valname,(LPDWORD)keyname,lptype,(LPBYTE)data,lplen)
#define OpenKeyHKLM(keyname,pkeyret)                    RegOpenKeyExW(HKEY_LOCAL_MACHINE,keyname,0, 0,pkeyret)

#define GetKey(keyin,valname,lptype,data,lplen)         RegQueryValueExW(keyin,valname,0,lptype,(LPBYTE)data,lplen)
#define OpenKey(keyin,keyname,pkeyret)                  RegOpenKeyExW(keyin,keyname,0, 0,pkeyret)


//
// maintain a local base time/tick to avoid calling GetRealTime
//
static LARGE_INTEGER gBaseFT;
static DWORD    gdwBaseTick;
static DWORD    gdwTimeChangeCnt;
static BOOL     gfUseSoftRTC;

BOOL InitSysTime (void)
{
    if (IsAPIReady (SH_FILESYS_APIS)) {
        DWORD type;
        DWORD size = sizeof(DWORD);
        // Query "HKLM\Platform\SoftRTC" to see if we should use SoftRTC or not.
        // If the query fails, gfUseSoftRTC remains 0 and we'll use Hardware RTC.
        GetKeyHKLM (L"SoftRTC", L"Platform", &type, (LPBYTE)&gfUseSoftRTC, &size);
        gdwTimeChangeCnt = TIME_CHANGE_CNT + 0x7fffffff;
    }

    return TRUE;
}

void GetLocalTimeAsFileTime (LPFILETIME lpft)
{
    SYSTEMTIME st;
    DWORD dwTick;

    // kernel will ensure that UserKInfo[KINX_TIMECHANGECOUNT] be incremented when
    // (1) time/timezone changed
    // (2) more then one day passed

    if (gfUseSoftRTC) {

        DWORD dwTimeChangeCnt = gdwTimeChangeCnt;

        dwTick = GetTickCount ();
        if (TIME_CHANGE_CNT == dwTimeChangeCnt) {
            // try to calculate the result locally, as long as time doesn't change
            LARGE_INTEGER li;

            // FILETIME is in 100ns
            li.QuadPart = gBaseFT.QuadPart + ((__int64) (DWORD) (dwTick - gdwBaseTick)) * 10000;
            if (TIME_CHANGE_CNT == dwTimeChangeCnt) {
                lpft->dwHighDateTime = li.HighPart;
                lpft->dwLowDateTime = li.LowPart;
                return;
            }
        }
    }

    GetRealTime (&st);
    SystemTimeToFileTime (&st, lpft);

    if (gfUseSoftRTC) {
        gBaseFT.HighPart = lpft->dwHighDateTime;
        gBaseFT.LowPart = lpft->dwLowDateTime;
        gdwBaseTick = dwTick;
        // update nounce last
        gdwTimeChangeCnt = TIME_CHANGE_CNT;
    }

}

void GetCurrentFT (LPFILETIME lpft)
{
    FILETIME ft;
    GetLocalTimeAsFileTime (&ft);
    LocalFileTimeToFileTime(&ft, lpft);
}

/*
    @doc BOTH EXTERNAL

    @func LONG | CompareFileTime | Compares two 64-bit file times.
    @parm CONST FILETIME * | lpFileTime1 | address of first file time
    @parm CONST FILETIME * | lpFileTime2 | address of second file time

    @devnote CHOOSE COMM TAG FOR ONLY ONE OF THE FOLLOWING:
    @comm Follows the Win32 reference description without restrictions or modifications.

*/
LONG WINAPI CompareFileTime(const FILETIME *lpft1, const FILETIME *lpft2) {
    if (lpft1->dwHighDateTime < lpft2->dwHighDateTime)
        return -1;
    else if (lpft1->dwHighDateTime > lpft2->dwHighDateTime)
        return 1;
    else if (lpft1->dwLowDateTime < lpft2->dwLowDateTime)
        return -1;
    else if (lpft1->dwLowDateTime > lpft2->dwLowDateTime)
        return 1;
    return 0;
}

void
mul64_32_64(
    const    FILETIME*    lpnum1,
            DWORD        num2,
            LPFILETIME    lpres
    )
{
    __int64 num1;

    num1 = (__int64)lpnum1->dwLowDateTime * (__int64)num2;
    num1 += ((__int64)lpnum1->dwHighDateTime * (__int64)num2)<<32;
    lpres->dwHighDateTime = (DWORD)(num1>>32);
    lpres->dwLowDateTime = (DWORD)(num1&0xffffffff);
}

void add64_32_64(const FILETIME *lpnum1, DWORD num2, LPFILETIME lpres) {
    DWORD bottom = lpnum1->dwLowDateTime + num2;
    lpres->dwHighDateTime = lpnum1->dwHighDateTime +
        (bottom < lpnum1->dwLowDateTime ? 1 : 0);
    lpres->dwLowDateTime = bottom;
}


void add64_64_64(const FILETIME *lpnum1, LPFILETIME lpnum2, LPFILETIME lpres) {
    LARGE_INTEGER li1, li2;
    li1.LowPart  = lpnum1->dwLowDateTime;
    li1.HighPart = lpnum1->dwHighDateTime;
    li2.LowPart  = lpnum2->dwLowDateTime;
    li2.HighPart = lpnum2->dwHighDateTime;

    li1.QuadPart += li2.QuadPart;
    lpres->dwHighDateTime = li1.HighPart;
    lpres->dwLowDateTime = li1.LowPart;
}

void sub64_64_64(const FILETIME *lpnum1, LPFILETIME lpnum2, LPFILETIME lpres) {
    LARGE_INTEGER li1, li2;
    li1.LowPart  = lpnum1->dwLowDateTime;
    li1.HighPart = lpnum1->dwHighDateTime;
    li2.LowPart  = lpnum2->dwLowDateTime;
    li2.HighPart = lpnum2->dwHighDateTime;

    li1.QuadPart -= li2.QuadPart;
    lpres->dwHighDateTime = li1.HighPart;
    lpres->dwLowDateTime = li1.LowPart;
}

// Unsigned divide
// Divides a 64 bit number by a *31* bit number.  Doesn't work for 32 bit divisors!

void div64_32_64(const FILETIME *lpdividend, DWORD divisor, LPFILETIME lpresult) {
    DWORD bitmask;
    DWORD top;
    FILETIME wholetop = *lpdividend;
    top = 0;
    lpresult->dwHighDateTime = 0;
    for (bitmask = 0x80000000; bitmask; bitmask >>= 1) {
        top = (top<<1) + ((wholetop.dwHighDateTime&bitmask) ? 1 : 0);
        if (top >= divisor) {
            top -= divisor;
            lpresult->dwHighDateTime |= bitmask;
        }
    }
    lpresult->dwLowDateTime = 0;
    for (bitmask = 0x80000000; bitmask; bitmask >>= 1) {
        top = (top<<1) + ((wholetop.dwLowDateTime&bitmask) ? 1 : 0);
        if (top >= divisor) {
            top -= divisor;
            lpresult->dwLowDateTime |= bitmask;
        }
    }
}

void DaysAndFractionToTime(ULONG ElapsedDays, ULONG Milliseconds, LPFILETIME lpTime) {
    lpTime->dwLowDateTime = ElapsedDays;
    lpTime->dwHighDateTime = 0;
    // Get number of milliseconds from days
    mul64_32_64(lpTime,86400000,lpTime);
    // Add in number of milliseconds
    add64_32_64(lpTime,Milliseconds,lpTime);
    // Convert to 100ns periods
    mul64_32_64(lpTime,10000,lpTime);
}

VOID TimeToDaysAndFraction(const FILETIME *lpTime, LPDWORD lpElapsedDays, LPDWORD lpMilliseconds) {
    FILETIME Temp, Temp2;
    // Convert 100ns periods to milliseconds
    Temp = *lpTime;
    div64_32_64(&Temp,10000,&Temp);
    // Get number of days
    div64_32_64(&Temp,86400000,&Temp2);
    *lpElapsedDays = Temp2.dwLowDateTime;
    mul64_32_64(&Temp2,86400000,&Temp2);
    sub64_64_64(&Temp,&Temp2,&Temp);
    *lpMilliseconds = Temp.dwLowDateTime;
}

ULONG ElapsedDaysToYears(ULONG ElapsedDays) {
    ULONG NumberOf400s;
    ULONG NumberOf100s;
    ULONG NumberOf4s;

    //  A 400 year time block is 146097 days
    NumberOf400s = ElapsedDays / 146097;
    ElapsedDays -= NumberOf400s * 146097;
    //  A 100 year time block is 36524 days
    //  The computation for the number of 100 year blocks is biased by 3/4 days per
    //  100 years to account for the extra leap day thrown in on the last year
    //  of each 400 year block.
    NumberOf100s = (ElapsedDays * 100 + 75) / 3652425;
    ElapsedDays -= NumberOf100s * 36524;
    //  A 4 year time block is 1461 days
    NumberOf4s = ElapsedDays / 1461;
    ElapsedDays -= NumberOf4s * 1461;
    return (NumberOf400s * 400) + (NumberOf100s * 100) +
           (NumberOf4s * 4) + (ElapsedDays * 100 + 75) / 36525;
}

BOOL IsValidSystemTime(const SYSTEMTIME *lpst) {
    if ((lpst->wYear < 1601) ||
        (lpst->wMonth < 1) ||
        (lpst->wMonth > 12) ||
        (lpst->wDay < 1) ||
        (lpst->wDay > MaxDaysInMonth(lpst->wYear,lpst->wMonth-1)) ||
        (lpst->wHour > 23) ||
        (lpst->wMinute > 59) ||
        (lpst->wSecond > 59) ||
        (lpst->wMilliseconds > 999))
        return FALSE;
    return TRUE;
}

/*
    @doc BOTH EXTERNAL

    @func BOOL | SystemTimeToFileTime | Converts a system time to a file time.
    @parm CONST SYSTEMTIME * | lpst | address of system time to convert
    @parm LPFILETIME | lpft | address of buffer for converted file time

    @comm Follows the Win32 reference description without restrictions or modifications.
*/
BOOL WINAPI SystemTimeToFileTime(const SYSTEMTIME *lpst, LPFILETIME lpft) {
    ULONG ElapsedDays;
    ULONG ElapsedMilliseconds;

    if (!IsValidSystemTime(lpst)) {
        SetLastError (ERROR_INVALID_PARAMETER);
        return FALSE;
    }
    ElapsedDays = ElapsedYearsToDays(lpst->wYear - 1601);
    ElapsedDays += (IsLeapYear(lpst->wYear) ?
        LeapYearDaysBeforeMonth[lpst->wMonth-1] :
        NormalYearDaysBeforeMonth[lpst->wMonth-1]);
    ElapsedDays += lpst->wDay - 1;
    ElapsedMilliseconds = (((lpst->wHour*60) + lpst->wMinute)*60 +
       lpst->wSecond)*1000 + lpst->wMilliseconds;
    DaysAndFractionToTime(ElapsedDays, ElapsedMilliseconds, lpft);
    return TRUE;
}

/*
    @doc BOTH EXTERNAL

    @func BOOL | FileTimeToSystemTime | Converts a 64-bit file time to system time format.
    @parm CONST FILETIME * | lpFileTime | pointer to file time to convert
    @parm LPSYSTEMTIME | lpSystemTime | pointer to structure to receive system time

    @comm Follows the Win32 reference description without restrictions or modifications.

*/
BOOL WINAPI FileTimeToSystemTime(const FILETIME *lpft, LPSYSTEMTIME lpst) {
    ULONG Days;
    ULONG Years;
    ULONG Minutes;
    ULONG Seconds;
    ULONG Milliseconds;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -