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

📄 dst.cpp

📁 该代码压缩包只为需要研究CE下的任务管理器的实现而提供的。某些通用的头文件没有包含在其中
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*---------------------------------------------------------------------------*\
 *  module: dst.cpp
 *  purpose: DST support.  Need to handle the following 3 scenarios
 *          1)  DST turns on/off when system is running
 *          2)  DST turns on/off when system is suspended
 *          3)  DST turns on/off when system is powered off
 *
\*---------------------------------------------------------------------------*/

#ifndef NODSTSAMPLE   //don't use this if NODSTSAMPLE is defined

#ifdef TASKMANDSTSAMPLE
#include "windows.h"
#include "minshell.h"
#else
#include "explorer.h"
#endif  //TASKMANDSTSAMPLE

#include <notify.h>

//keep these consistant with names in public\wceshellfe\oak\ctlpnl\cplmain\regcpl.h
#define RK_CLOCK        TEXT("Software\\Microsoft\\Clock")
#define RV_INDST        TEXT("HomeDST")  //are we in DST?
#define RV_AUTODST      TEXT("AutoDST")  //do we auto-adjust DST?
#define RV_DSTUI        TEXT("ShowDSTUI")  //do we show a message at dst change?

#define DSTEVENT          _T("ShellDSTEvent")
#define DSTTZEVENT        _T("DSTTzChange")
#define DSTTIMEEVENT        _T("DSTTimeChange")

#define DSTNOTIFICATION   _T("\\\\.\\Notifications\\NamedEvents\\ShellDSTEvent")
#define DSTTIMEZONENOTIFICATION _T("\\\\.\\Notifications\\NamedEvents\\DSTTzChange")
#define DSTTIMENOTIFICATION _T("\\\\.\\Notifications\\NamedEvents\\DSTTimeChange")

#define NUMDSTEVENTS 3
#define TZCHANGEEVENT 0
#define TIMECHANGEEVENT 1
#define DSTCHANGEEVENT 2 // This event must be last so WaitForMultipleObjects algorithm works (see DST_WaitForEvents)

#define MAX_DSTMSGLEN 256
#define MAX_DSTTITLELEN 64

// FILETIME (100-ns intervals) to minutes (10 x 1000 x 1000 x 60)
#define FILETIME_TO_MINUTES (10 * 1000 * 1000 * 60)

#define FIRST_OF_MONTH      1
#define SECOND_OF_MONTH     2
#define THIRD_OF_MONTH      3
#define FOURTH_OF_MONTH     4
#define LAST_OF_MONTH       5

const int AccumDaysByMonth[13] =
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };

DWORD g_dwTime = TIME_ZONE_ID_STANDARD;


/*++

    
Routine Description:
    Determines whether the current date and time is in daylight
    or standard time, and notifies the kernel.

    Kernel doesn't currently update this in all cases
    Manually take care of it to be safe and ensure that subsequent calls 
    to GetTimeZoneInformation return the correct value

    
Arguments:
    none
    
Return Value:
    current timezone value (same as return values for GetTimeZoneInformation
    
--*/
void  DST_SetDaylightOrStandardTime(void)
{
    TIME_ZONE_INFORMATION tzi;
    DWORD dwTZ = GetTimeZoneInformation(&tzi);

    // If the system supports DST verify that the kernel returned the correct
    // value, otherwise make sure the kerel has us in SDT
    if (LocaleSupportsDST(&tzi))
    {
        SYSTEMTIME curTime;
        LONGLONG  llStandard = 0, llDaylight = 0, llNow = 0;

        GetLocalTime(&curTime);

        //fix up the date structs if necessary
        if (0 == tzi.StandardDate.wYear)
            DST_DetermineChangeDate(&tzi.StandardDate);
        if (0 == tzi.DaylightDate.wYear)
            DST_DetermineChangeDate(&tzi.DaylightDate);

        //convert so we can do the math
        VERIFY(SystemTimeToFileTime(&tzi.StandardDate, (FILETIME *)&llStandard));
        VERIFY(SystemTimeToFileTime(&tzi.DaylightDate, (FILETIME *)&llDaylight));
        VERIFY(SystemTimeToFileTime(&curTime, (FILETIME *)&llNow));

        //the greater difference determines which zone we are in   
        if ((llStandard - llNow) < (llDaylight - llNow))
        {
            DEBUGMSG(ZONE_DST, (_T("DST:  Notifying kernel that we are in Daylight time.  GetTimeZoneInformation currently thinks we are in %s time."), 
                     TIME_ZONE_ID_DAYLIGHT  == dwTZ ? _T("Daylight") : _T("Standard")));
            SetDaylightTime(TRUE);
            g_dwTime = TIME_ZONE_ID_DAYLIGHT;
        }
        else
        {
            DEBUGMSG(ZONE_DST, (_T("DST:  Notifying kernel that we are in Standard time.  GetTimeZoneInformation currently thinks we are in %s time."), 
                     TIME_ZONE_ID_DAYLIGHT  == dwTZ ? _T("Daylight") : _T("Standard")));
            SetDaylightTime(FALSE);
            g_dwTime = TIME_ZONE_ID_STANDARD;
        }
    }
    else
    {
        ASSERT(TIME_ZONE_ID_STANDARD == dwTZ);
        if (TIME_ZONE_ID_STANDARD != dwTZ)
            SetDaylightTime(FALSE);
        g_dwTime = TIME_ZONE_ID_STANDARD;
    }
}


/*++
Routine Description:
    'main' function for DST.  Called from shell init, and re-entered from DST_WaitForEvent.
    
Arguments:
    none
    
Return Value:
    none
    
--*/
void DST_Init(void)
{
    //need to know from the start if we are in standard or daylight time
    DST_SetDaylightOrStandardTime();
    for (;;)
    {
        HANDLE hDSTEvents[NUMDSTEVENTS];
        hDSTEvents[TZCHANGEEVENT] = DST_SetTimezoneChangeEvent();
        hDSTEvents[TIMECHANGEEVENT] = DST_SetTimeChangeEvent();
        hDSTEvents[DSTCHANGEEVENT] = DST_SetDSTEvent(); // This can be NULL if we are in a non-DST timezone

        if (NULL == hDSTEvents[TZCHANGEEVENT])
        {
            DEBUGCHK( _T("DST:  Failed to set TZ change Event"));
            break;
        }
        if (NULL == hDSTEvents[TIMECHANGEEVENT])
        {
            DEBUGCHK( _T("DST:  Failed to set Time change Event"));
            break;
        }

        DST_WaitForEvents(hDSTEvents);
    } 

}    


/*++
Routine Description:
    Determines if we should auto-adjust for DST
    
Arguments:
    none
    
Return Value:
    TRUE if we want to auto adjust
    FALSE if we don't want to auto adjust
    
--*/
BOOL  DST_Auto(void)
{
    DWORD ret = 0;
    HKEY hKey = NULL;
    if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, RK_CLOCK, 0, 0, &hKey))
    {
        DWORD dwSize = sizeof(DWORD);
        RegQueryValueEx(hKey, RV_AUTODST, 0, NULL, (LPBYTE)&ret, &dwSize);
        RegCloseKey(hKey);
    }
#ifdef DEBUG
    if (ret)
    {
        DEBUGMSG(ZONE_DST, ( _T("DST:  Auto change for DST is on")));
    } 
    else
    {
        DEBUGMSG(ZONE_DST, ( _T("DST:  Auto change for DST is off")));
    }
#endif //DEBUG

    return (BOOL)ret;
}



/*++
Routine Description:
    Determines if we should show a mesage for DST change
    
Arguments:
    none
    
Return Value:
    TRUE if we want to show a message
    FALSE if we don't want to show a message
    
--*/
BOOL  DST_ShowMessage(void)
{
    DWORD ret = 0;
    HKEY hKey = NULL;
    if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, RK_CLOCK, 0, 0, &hKey))
    {
        DWORD dwSize = sizeof(DWORD);
        RegQueryValueEx(hKey, RV_DSTUI, 0, NULL, (LPBYTE)&ret, &dwSize);
        RegCloseKey(hKey);
    }
#ifdef DEBUG
    if (ret)
    {
        DEBUGMSG(ZONE_DST, ( _T("DST:  Show Message option for DST is on")));
    } 
    else
    {
        DEBUGMSG(ZONE_DST, ( _T("DST:  Show Message option for DST is off")));
    }
#endif //DEBUG

    return (BOOL)ret;
}

/*++

    
Routine Description:
    Sets Event to be notified when timezone changes
    
Arguments:
    none
    
Return Value:
    HANDLE to timezone event
    
--*/
HANDLE DST_SetTimezoneChangeEvent(void)
{
    HANDLE hTZEvent = CreateEvent(NULL, FALSE, FALSE, DSTTZEVENT);
    if (hTZEvent)
    {
        if (!CeRunAppAtEvent(DSTTIMEZONENOTIFICATION,
                             NOTIFICATION_EVENT_TZ_CHANGE))
        {
            CloseHandle(hTZEvent);
            hTZEvent = NULL;
        }
    }
    return hTZEvent;
}

/*++

    
Routine Description:
    Sets Event to be notified when time changes
    
Arguments:
    none
    
Return Value:
    HANDLE to timezone event
    
--*/
HANDLE DST_SetTimeChangeEvent(void)
{
    HANDLE hTimeEvent = CreateEvent(NULL, FALSE, FALSE, DSTTIMEEVENT);
    if (hTimeEvent)
    {
        if (!CeRunAppAtEvent(DSTTIMENOTIFICATION,
                             NOTIFICATION_EVENT_TIME_CHANGE))
        {
            CloseHandle(hTimeEvent);
            hTimeEvent = NULL;
        }
    }
    return hTimeEvent;
}


/*++
Routine Description:
    Sets the DST Event 
    
Arguments:
    none
    
Return Value:
    Handle to event to be triggered when daylight time turns on (or off)
    
--*/
HANDLE DST_SetDSTEvent (void)
{
    HANDLE hEvent = NULL;
    BOOL bEvent = FALSE;
    TIME_ZONE_INFORMATION tzi = {0};
    SYSTEMTIME curTime, notificationTime;
    LONGLONG llNow = 0, llNotification = 0;

    DWORD dwTZ = GetTimeZoneInformation(&tzi);

    // Only create the event if the locale supports DST
    if (!LocaleSupportsDST(&tzi))
        return NULL;

⌨️ 快捷键说明

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