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

📄 pmstubs.cpp

📁 此代码为WCE5.0下电源管理的源代码
💻 CPP
字号:
//
// 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 Name:

    pmstubs.cpp

Abstract:

    Empty PM APIs, solely to satisfy the linker.

Revision History:

--*/

#include <windows.h>
#include <pm.h>
#include <extfile.h>

#define _DEFINE_PM_VARS     // global variables defined in this module

#include <pmimpl.h>

typedef BOOL (WINAPI * PFN_GwesPowerDown)(void);
typedef void (WINAPI * PFN_GwesPowerUp)(BOOL);

// force C linkage to match external variable declarations
extern "C" {

// define list pointers
PPOWER_NOTIFICATION gpPowerNotifications;

// other globals
CRITICAL_SECTION gcsPowerManager;   // serialize access to PM data
CRITICAL_SECTION gcsDeviceUpdateAPIs; // serialize application calls that cause device updates
HINSTANCE ghInst;                   // handle to the PM DLL
HANDLE ghevPowerManagerReady;       // when set, this event means that the PM api is enabled
HANDLE ghPmHeap;                    // power manager's memory allocation heap
HANDLE ghevPmShutdown;              // signal to cause PM threads to exit
HANDLE ghevGwesReady;
BOOL gfGwesReady;
PFN_GwesPowerDown gpfnGwesPowerDown;
PFN_GwesPowerUp gpfnGwesPowerUp;
POWER_BROADCAST_POWER_INFO gSystemPowerStatus;

#if defined(DEBUG) || !defined(_PM_NOCELOGMSG)
#define DBG_ERROR           (1 << 0)
#define DBG_WARN            (1 << 1)
#define DBG_INIT            (1 << 2)
#define DBG_REGISTRY        (1 << 9)
#define DBG_PLATFORM        (1 << 10)
#define DBG_API             (1 << 11)
#define DBG_ALLOC           (1 << 12)

DBGPARAM dpCurSettings = {
    _T("PM"), 
    {
        TEXT("Errors"), TEXT("Warnings"), TEXT("Init"), TEXT(""), 
        TEXT(""), TEXT(""), TEXT(""), TEXT(""),
        TEXT("Notify"),TEXT("Registry"),TEXT("Platform"),TEXT("API"),
        TEXT("Alloc"),TEXT(""),TEXT(""),TEXT("") 
    },
    DBG_ERROR | DBG_WARN | DBG_INIT
}; 
#endif

};      // extern "C"

EXTERN_C BOOL WINAPI
PmInit(VOID)
{
    BOOL fOk = TRUE;
    HMODULE hmCoreDll = NULL;
    SETFNAME(_T("PmInit"));

    DEBUGMSG(ZONE_INIT || ZONE_API, (_T("+%s\r\n"), pszFname));

    // set up globals
    InitializeCriticalSection(&gcsPowerManager);
    InitializeCriticalSection(&gcsDeviceUpdateAPIs);
    gpPowerNotifications = NULL;
    ghPmHeap = GetProcessHeap();
    ghevPowerManagerReady = NULL;
    gpfnGwesPowerDown = NULL;
    gpfnGwesPowerUp = NULL;

    // cleanup event (hopefully never used)
    ghevPmShutdown = CreateEvent(NULL, TRUE, FALSE, NULL);
    if(ghevPmShutdown == NULL) {
        DEBUGMSG(ZONE_ERROR, (_T("%s: CreateEvent() failed for shutdown event\r\n"), pszFname));
        fOk = FALSE;
    } 
    // create events
    if(fOk) {
        ghevPowerManagerReady = CreateEvent(NULL, TRUE, FALSE, _T("SYSTEM/PowerManagerReady"));

        // check everything
        if(ghevPowerManagerReady == NULL) {
            DEBUGMSG(ZONE_ERROR, (_T("%s: event creation failure\r\n"), pszFname));
            fOk = FALSE;
        }
    }

    // Get pointers to GWES's suspend/routine APIs.  These require GWES, so the OEM may
    // not have them on this platform.
    if(fOk) {
        hmCoreDll = (HMODULE) LoadLibrary(_T("coredll.dll"));
        gfGwesReady = FALSE;
        if(hmCoreDll != NULL) {
            gpfnGwesPowerDown = (PFN_GwesPowerDown) GetProcAddress(hmCoreDll, _T("GwesPowerDown"));
            gpfnGwesPowerUp = (PFN_GwesPowerUp) GetProcAddress(hmCoreDll, _T("GwesPowerUp"));
            
            // do we have both of them?
            if(gpfnGwesPowerDown == NULL || gpfnGwesPowerUp == NULL) {
                // no, ignore GWES
                gpfnGwesPowerDown = NULL;
                gpfnGwesPowerUp = NULL;
            } else {
                // monitor GWES apis
                ghevGwesReady = OpenEvent(EVENT_ALL_ACCESS, FALSE, _T("SYSTEM/GweApiSetReady"));
                DEBUGCHK(ghevGwesReady != NULL);
                if(ghevGwesReady == NULL) {
                    fOk = FALSE;
                }
            }
        }
    }

    // if everything is initialized, we're ready start the power monitor thread
    if(fOk) {
        BOOL fGotBatteryAPIs = PmInitPowerStatus(hmCoreDll);
        if(fGotBatteryAPIs) {
            DWORD WINAPI PowerMonitorThreadProc(LPVOID lpvParam);
            HANDLE htMonitor = CreateThread(NULL, 0, PowerMonitorThreadProc, NULL, 0, NULL);
            if(htMonitor == NULL) {
                DEBUGMSG(ZONE_WARN, (_T("%s: CreateThread() failed %d for power monitor thread\r\n"),
                    pszFname, GetLastError()));
            } else {
                CloseHandle(htMonitor);
            }
        }
    } 
    
    // should we signal that our API is ready?
    if(fOk) {
        // yes, the PM is initialized
        SetEvent(ghevPowerManagerReady);
    } else {
        // no, clean up
        DEBUGMSG(ZONE_ERROR, (_T("%s: closing handles\r\n"), pszFname));
        if(ghevPowerManagerReady != NULL) CloseHandle(ghevPowerManagerReady);
        if(ghevGwesReady != NULL) CloseHandle(ghevGwesReady);
        if(hmCoreDll != NULL) FreeLibrary(hmCoreDll);
        if(ghevPmShutdown != NULL) CloseHandle(ghevPmShutdown);
    }

    DEBUGMSG((!fOk && ZONE_ERROR) || ZONE_INIT || ZONE_API, 
        (_T("-%s: returning %d\r\n"), pszFname, fOk));

    DEBUGCHK(fOk);      // make sure we raise a red flag if the init fails

    return fOk;
}

// This routine receives notifications from the system about various system
// events, including processes exiting.  Some of the messages have the same
// names as DllEntry() messages, but the resemblance is superficial.  Note 
// that unlike DLL entry point message handlers, these notifications allow
// the message handler to use synchronization objects without deadlocking
// the system.
EXTERN_C VOID WINAPI 
PmNotify(DWORD dwFlags, HPROCESS hProcess, HTHREAD hThread)
{
    SETFNAME(_T("PmNotify"));

    UnusedParameter(hThread);

    switch(dwFlags) {
    case DLL_PROCESS_DETACH:
        // release any resources held by this process
        DEBUGMSG(ZONE_API, (_T("+%s: hProcess 0x%08x exiting\r\n"), pszFname, hProcess));
        DeleteProcessNotifications(hProcess);
        DEBUGMSG(ZONE_API, (_T("-%s\r\n"), pszFname));
        break;
    default:
        break;
    }
}

DWORD WINAPI
PmSetDevicePower(
    PVOID pvDevice, 
    DWORD dwDeviceFlags, 
    CEDEVICE_POWER_STATE DeviceState
    )
{
    SetLastError(ERROR_SERVICE_DOES_NOT_EXIST);
    return ERROR_SERVICE_DOES_NOT_EXIST;
}


DWORD WINAPI
PmGetDevicePower(
    PVOID pvDevice, 
    DWORD dwDeviceFlags,
    PCEDEVICE_POWER_STATE pDeviceState
    )
{
    SetLastError(ERROR_SERVICE_DOES_NOT_EXIST);
    return ERROR_SERVICE_DOES_NOT_EXIST;
}

DWORD WINAPI
PmDevicePowerNotify(
    PVOID                   pvDevice,
    CEDEVICE_POWER_STATE    DeviceState,
    DWORD                   Flags
    )
{
    SetLastError(ERROR_SERVICE_DOES_NOT_EXIST);
    return ERROR_SERVICE_DOES_NOT_EXIST;
}


DWORD WINAPI
PmGetSystemPowerState(
    LPWSTR  pBuffer,
    DWORD   Length,
    PDWORD  pFlags
    )
{
    SetLastError(ERROR_SERVICE_DOES_NOT_EXIST);
    return ERROR_SERVICE_DOES_NOT_EXIST;
}


DWORD WINAPI
PmReleasePowerRequirement(
    HANDLE  h,
    DWORD   Flags
    )
{
    SetLastError(ERROR_SERVICE_DOES_NOT_EXIST);
    return ERROR_SERVICE_DOES_NOT_EXIST;
}

HANDLE WINAPI
PmRegisterPowerRelationship(
    PVOID pvParent,             // e.g. 'NDS0:'
    PVOID pvChild,              // e.g. 'NE20001', 'NE20002', ...
    PPOWER_CAPABILITIES pCaps,  // OPTIONAL Child's capabilities
    DWORD   Flags
    )
{
    SetLastError(ERROR_SERVICE_DOES_NOT_EXIST);
    return INVALID_HANDLE_VALUE;
}

DWORD WINAPI
PmReleasePowerRelationship(
    HANDLE h
    )
{
    SetLastError(ERROR_SERVICE_DOES_NOT_EXIST);
    return ERROR_SERVICE_DOES_NOT_EXIST;
}

HANDLE WINAPI
PmSetPowerRequirement(
    PVOID                   pvDevice,
    CEDEVICE_POWER_STATE    DeviceState,
    ULONG                   DeviceFlags,
    PVOID                   pvSystemState,  // OPTIONAL
    ULONG                   StateFlags      // OPTIONAL
    )
{
    SetLastError(ERROR_SERVICE_DOES_NOT_EXIST);
    return INVALID_HANDLE_VALUE;
}


EXTERN_C DWORD WINAPI 
PmSetSystemPowerState(LPCWSTR pwsState, DWORD dwStateHint, DWORD dwOptions)
{
    DWORD dwStatus = ERROR_SUCCESS;
    SETFNAME(_T("PmSetSystemPowerState"));

    DEBUGMSG(ZONE_API, (_T("+%s: name %s, hint 0x%08x, options 0x%08x\r\n"),
        pszFname, pwsState != NULL ? pwsState : _T("<NULL>"), dwStateHint, dwOptions));

    PMENTERUPDATE();

    // are we being asked to suspend the system?
    if(pwsState != NULL 
    || (dwStateHint & (POWER_STATE_SUSPEND | POWER_STATE_OFF | POWER_STATE_CRITICAL)) == 0) {
        // no, return an error
        SetLastError(ERROR_SERVICE_DOES_NOT_EXIST);
        dwStatus = ERROR_SERVICE_DOES_NOT_EXIST;
    } else {
        // are the GWES suspend APIs present and ready?
        if(!gfGwesReady && gpfnGwesPowerDown != NULL) {
            // APIs present, but not ready -- check for readiness
            if(WaitForSingleObject(ghevGwesReady, 0) == WAIT_OBJECT_0) {
                gfGwesReady = TRUE;
                CloseHandle(ghevGwesReady);
                ghevGwesReady = NULL;
            }
        }

        // suspend the system
        BOOL fWantStartupScreen = FALSE;
        if(gfGwesReady && gpfnGwesPowerDown != NULL) {
            fWantStartupScreen = gpfnGwesPowerDown();
        }
        KernelIoControl(IOCTL_HAL_PRESUSPEND, NULL, 0, NULL, 0, NULL);
        FileSystemPowerFunction(FSNOTIFY_POWER_OFF);
        PowerOffSystem();
        Sleep(0);
        FileSystemPowerFunction(FSNOTIFY_POWER_ON);
        if(gfGwesReady && gpfnGwesPowerUp != NULL) {
            gpfnGwesPowerUp(fWantStartupScreen);
        }
    }

    PMLEAVEUPDATE();

    DEBUGMSG(ZONE_API, (_T("-%s: returning dwStatus %d\r\n"), pszFname, dwStatus));

    return dwStatus;
}

VOID WINAPI PmPowerHandler(BOOL bOff)
{
    UnusedParameter(bOff);
}

// dll entry point
BOOL WINAPI
DllEntry(HANDLE hInst, DWORD  dwReason, LPVOID lpvReserved) 
{
    BOOL bRc = TRUE;
    SETFNAME(_T("Power Manager"));
    
    UnusedParameter(hInst);
    UnusedParameter(lpvReserved);
    
    switch (dwReason) {
    case DLL_PROCESS_ATTACH:
        ghInst = (HINSTANCE) hInst;
        DEBUGREGISTER(ghInst);
        DEBUGMSG(ZONE_INIT,(TEXT("*** %s: DLL_PROCESS_ATTACH - Current Process: 0x%x, ID: 0x%x ***\r\n"),
            pszFname, GetCurrentProcess(), GetCurrentProcessId()));
        DisableThreadLibraryCalls((HMODULE) hInst);
        break;
        
    case DLL_PROCESS_DETACH:
        DEBUGMSG(ZONE_INIT,(TEXT("*** %s: DLL_PROCESS_DETACH - Current Process: 0x%x, ID: 0x%x ***\r\n"),
            pszFname, GetCurrentProcess(), GetCurrentProcessId()));
        break;
        
    default:
        break;
    }
   
    return bRc;
}

⌨️ 快捷键说明

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