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

📄 mon.c

📁 此代码为WCE5.0下电源管理的源代码
💻 C
📖 第 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 Name:

    mon.c

Abstract:

    Power Manager Monitor.
    Run in the background to display power state changes in debugger.

Notes:

Revision History:

--*/

#include <windows.h>
#include <msgqueue.h>
#include <pnp.h>
#include <guiddef.h>
#include <pm.h>

#define QUEUE_ENTRIES   3
#define MAX_NAMELEN     200
#define QUEUE_SIZE      (QUEUE_ENTRIES * (sizeof(POWER_BROADCAST) + MAX_NAMELEN))

// device notification queue parameters
#define PNP_QUEUE_ENTRIES       3
#define PNP_MAX_NAMELEN         128
#define PNP_QUEUE_SIZE          (PNP_QUEUE_ENTRIES * (sizeof(DEVDETAIL) + (PNP_MAX_NAMELEN * sizeof(TCHAR))))

#define PWRMGR_REG_KEY      TEXT("SYSTEM\\CurrentControlSet\\Control\\Power")

// global variables
HANDLE ghPowerNotifications = NULL;
HANDLE ghDeviceNotifications = NULL;
HANDLE ghevTerminate = NULL;

void ProcessPowerNotification(HANDLE hMsgQ)
{
    UCHAR buf[QUEUE_SIZE];
    int iBytesInQueue;
    DWORD dwFlags = 0;
    int dwCount = 0;
    LPTSTR pszFname = _T("PMMON!ProcessPowerNotification");

    iBytesInQueue = 0;
    memset(buf, 0, QUEUE_SIZE);

    if ( !ReadMsgQueue(hMsgQ,
                       buf,
                       QUEUE_SIZE,
                       &iBytesInQueue,
                       INFINITE,    // Timeout
                       &dwFlags))
    {
        DWORD dwErr = GetLastError();
        RETAILMSG(1, (TEXT("%s: ReadMsgQueue: ERROR:%d\n"), pszFname, dwErr));
        ASSERT(0);
    } else if(iBytesInQueue >= sizeof(POWER_BROADCAST)) {
        //
        // process power notifications
        //
        PPOWER_BROADCAST pB = (PPOWER_BROADCAST) buf;
        
        RETAILMSG(1, (TEXT("%s: *** Power Notification @ Tick:%u, Count:%d***\n"), pszFname,
            GetTickCount(), dwCount++));
        switch (pB->Message) 
        {
        case PBT_TRANSITION:
            RETAILMSG(1, (TEXT("%s:\tPBT_TRANSITION to system power state: '%s'\n"), pszFname, pB->SystemPowerState));
            switch (POWER_STATE(pB->Flags)) {
            case POWER_STATE_ON:
                RETAILMSG(1, (TEXT("%s:\tPOWER_STATE_ON\n"), pszFname));
                break;
            case POWER_STATE_OFF:
                RETAILMSG(1, (TEXT("%s:\tPOWER_STATE_OFF\n"), pszFname));
                break;
            case POWER_STATE_CRITICAL:
                RETAILMSG(1, (TEXT("%s:\tPOWER_STATE_CRITICAL\n"), pszFname));
                break;
            case POWER_STATE_BOOT:
                RETAILMSG(1, (TEXT("%s:\tPOWER_STATE_BOOT\n"), pszFname));
                break;
            case POWER_STATE_IDLE:
                RETAILMSG(1, (TEXT("%s:\tPOWER_STATE_IDLE\n"), pszFname));
                break;
            case POWER_STATE_SUSPEND:
                RETAILMSG(1, (TEXT("%s:\tPOWER_STATE_SUSPEND\n"), pszFname));
                break;
            case POWER_STATE_RESET:
                RETAILMSG(1, (TEXT("%s:\tPOWER_STATE_RESET\n"), pszFname));
                break;
            case 0:
                break;
            default:
                RETAILMSG(1,(TEXT("%s:\tUnknown Power State Flags:0x%x\n"), pszFname, pB->Flags));
                ASSERT(0);
                break;
            }
            break;
            
            case PBT_RESUME:
                RETAILMSG(1, (TEXT("%s:\tPBT_RESUME\n"), pszFname));
                break;
                
            case PBT_POWERSTATUSCHANGE:
                RETAILMSG(1, (TEXT("%s:\tPBT_POWERSTATUSCHANGE\n"), pszFname));
                break;
                
            case PBT_POWERINFOCHANGE:
                {
                    PPOWER_BROADCAST_POWER_INFO ppbpi = (PPOWER_BROADCAST_POWER_INFO) pB->SystemPowerState;

                    RETAILMSG(1, (TEXT("%s:\tPBT_POWERINFOCHANGE\n"), pszFname));
                    RETAILMSG(1, (TEXT("%s:\t\tAC line status %u, battery flag %u, backup flag %u, %d levels\n"), pszFname,
                        ppbpi->bACLineStatus, ppbpi->bBatteryFlag, ppbpi->bBackupBatteryFlag, ppbpi->dwNumLevels));
                    RETAILMSG(1, (TEXT("%s:\t\tbattery life %d, backup life %d\n"), pszFname,
                        ppbpi->bBatteryLifePercent, ppbpi->bBackupBatteryLifePercent));
                    RETAILMSG(1, (TEXT("%s:\t\tlifetime 0x%08x, full lifetime 0x%08x\n"), pszFname, 
                        ppbpi->dwBatteryLifeTime, ppbpi->dwBatteryFullLifeTime));
                    RETAILMSG(1, (TEXT("%s:\t\tbackup lifetime 0x%08x, backup full lifetime 0x%08x\n"), pszFname, 
                        ppbpi->dwBackupBatteryLifeTime, ppbpi->dwBackupBatteryFullLifeTime));
                }
                break;
                
            default:
                RETAILMSG(1, (TEXT("%s:\tUnknown Message:%d\n"), pszFname, pB->Message));
                ASSERT(0);
                break;
        }

        RETAILMSG(1, (TEXT("%s:\tMessage: 0x%x\n"), pszFname, pB->Message));
        RETAILMSG(1, (TEXT("%s:\tFlags: 0x%x\n"), pszFname, pB->Flags));
        RETAILMSG(1, (TEXT("%s:\tdwLen: %d\n"), pszFname, pB->Length));
        
        RETAILMSG(1, (TEXT("%s:***********************\n"), pszFname));
    } else {
        RETAILMSG(1, (TEXT("%s:\tReceived short message: %d bytes\n"), pszFname, iBytesInQueue));
        ASSERT(0);
    }
}

void
ProcessDeviceNotification(HANDLE hMsgQ)
{
    UCHAR deviceBuf[PNP_QUEUE_SIZE];
    DWORD iBytesInQueue = 0;
    DWORD dwFlags = 0;
    LPTSTR pszFname = _T("PMMON!ProcessDeviceNotification");

    // read a message from the message queue -- it should be a device advertisement
    memset(deviceBuf, 0, PNP_QUEUE_SIZE);
    if ( !ReadMsgQueue(hMsgQ, deviceBuf, PNP_QUEUE_SIZE, &iBytesInQueue, 0, &dwFlags)) {
        // nothing in the queue
        RETAILMSG(TRUE, (_T("%s: ReadMsgQueue() failed %d\r\n"), pszFname,
            GetLastError()));
    } else if(iBytesInQueue >= sizeof(DEVDETAIL)) {
        // process the message
        PDEVDETAIL pDevDetail = (PDEVDETAIL) deviceBuf;
        DWORD dwMessageSize = sizeof(DEVDETAIL) + pDevDetail->cbName;
        
        // check for overlarge names
        if(pDevDetail->cbName > ((PNP_MAX_NAMELEN - 1) * sizeof(pDevDetail->szName[0]))) {
            RETAILMSG(TRUE, (_T("%s: device name longer than %d characters\r\n"), 
                pszFname, PNP_MAX_NAMELEN - 1));
        } else {
            LPCTSTR pszName = pDevDetail->szName;
            LPCGUID guidDevClass = &pDevDetail->guidDevClass;
            TCHAR szClassDescription[MAX_PATH];
            TCHAR szClassName[MAX_PATH];
            HKEY hk;
            DWORD dwStatus;

            // format the class name
            _stprintf(szClassName, _T("{%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x}"), 
                guidDevClass->Data1, guidDevClass->Data2, guidDevClass->Data3,
                (guidDevClass->Data4[0] << 8) + guidDevClass->Data4[1], guidDevClass->Data4[2], guidDevClass->Data4[3], 
                guidDevClass->Data4[4], guidDevClass->Data4[5], guidDevClass->Data4[6], guidDevClass->Data4[7]);

            // (inefficiently) look up the class description whenever a device registers
            wsprintf(szClassDescription, _T("%s\\Interfaces"), PWRMGR_REG_KEY);
            dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szClassDescription, 0, 0, &hk);
            if(dwStatus == ERROR_SUCCESS) {
                DWORD dwSize = sizeof(szClassDescription);
                dwStatus = RegQueryValueEx(hk, szClassName, NULL, NULL, (LPBYTE) szClassDescription, &dwSize);
                RegCloseKey(hk);
            }
            if(dwStatus != ERROR_SUCCESS) {
                _tcscpy(szClassDescription, (_T("<unknown class>")));
            }
            
            RETAILMSG(TRUE, 
                (_T("%s: device '%s' %s class %s ('%s')\r\n"), pszFname,
                pszName, pDevDetail->fAttached ? _T("joining") : _T("leaving"),
                szClassName, szClassDescription));
        }
    } else {
        // not enough bytes for a message
        RETAILMSG(TRUE, (_T("%s: got runt message (%d bytes)\r\n"), pszFname, 
            iBytesInQueue));
    }
}

int WINAPI MonThreadProc(LPVOID pvParam)
{

⌨️ 快捷键说明

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