App and driver 電源管理器註冊



電源註冊過程:


1、DevicePowerNotify

     Sends a request to the Power Manager about changing a power state
of a peripheral device.

2、RequestPowerNotifications (註冊電源管理器)

      Registers a message queue to receive power change notifications .
3、StopPowerNotifications

     Stops receiving power change notifications .

4、SetPowerRequirement

    Informs the Power Manager about power requirements of a given peripheral device .

5、ReleasePowerRequirement

     Informs Power Manager that it can release previously set power re- quirements of a given peripheral device .

6. SetSystemPowerState

A request sent to the Power Manager about changing a power state of the system as a whole .


IOCTL:


PM Example:


//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft
// premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license
// agreement, you are not authorized to use this source code.
// For the terms of the license, please see the license agreement
// signed by you and Microsoft.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
/*++


Module Name:

    api.c

Abstract:

    Power Manager API runthrough test (defunct).

Notes:

Revision History:

--*/

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

extern int	CreateArgvArgc(TCHAR *pProgName, TCHAR *argv[20], TCHAR *pCmdLine);

typedef enum _Cmd  {

    TEST_INFINITE     = 'i',
    TEST_ONCE         = 'o',
    PREMATURE_RELEASE = 'p',

} CMD;


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

HANDLE hMsgQ;

DWORD WINAPI 
PowerNotifyThread(
    LPVOID Context
    );

#ifdef DEBUG
DBGPARAM dpCurSettings = {
    TEXT("PMAPI"), {
    TEXT("Error"), TEXT("Warn"), TEXT("Thread"), TEXT("Trace")
    TEXT("5"),  TEXT("6"),  TEXT("7"),  TEXT("8")
    TEXT("9"),  TEXT("10"), TEXT("11"), TEXT("12")
    TEXT("13"), TEXT("14"), TEXT("15"), TEXT("16")
    },
    0x0007 // ZONE_WRN|ZONE_ERR|ZONE_THREAD
};
#define ZONE_ERR            DEBUGZONE(0)
#define ZONE_WRN            DEBUGZONE(1)
#define ZONE_THREAD         DEBUGZONE(2)
#define ZONE_TRACE          DEBUGZONE(3)
#endif  // DEBUG


DWORD
MyEnumRegValues(
    HKEY    hKey,
    LPCWSTR pState,
    DWORD   Len
    )
{
    WCHAR wsValBuff[MAX_PATH];
    BYTE  bData[MAX_PATH];
    DWORD iValue, dwValBuffLen, dwType, dwDataLen;
    DWORD dwErr = ERROR_SUCCESS;

    for (iValue = 0; ERROR_SUCCESS == dwErr; iValue++)
    {
        memset(&wsValBuff, 0, MAX_PATH);
        dwValBuffLen = MAX_PATH;
        dwType = 0;
        memset(&bData, 0, MAX_PATH);
        dwDataLen = MAX_PATH;

        dwErr = RegEnumValue(hKey,
                             iValue,
                             &wsValBuff[0],
                             &dwValBuffLen,
                             NULL,
                             &dwType, 
                             &bData[0],
                             &dwDataLen);

        if (ERROR_SUCCESS == dwErr) 
        {
            if (pState &&
                dwType == REG_DWORD && 
                sizeof(DWORD) == dwDataLen &&
                0 == wcsncmp(PM_FLAGS_SZ, wsValBuff, dwValBuffLen))
            {
                DWORD Flags = *(PDWORD)bData;

                switch (POWER_STATE(Flags))
                {
                case POWER_STATE_OFF:
                    DEBUGMSG(ZONE_TRACE, (TEXT("'%s' is a POWER_STATE_OFF\n"), pState));
                    continue;
                    
                case POWER_STATE_SUSPEND:
                    DEBUGMSG(ZONE_TRACE, (TEXT("'%s' is a POWER_STATE_SUSPEND\n"), pState));
                    continue;
                }
            }
        } else if (ERROR_NO_MORE_ITEMS != dwErr) {
            DEBUGMSG(ZONE_ERR, (TEXT("PMAPI!\tRegEnumValue ERROR:%d dwType:%d\n"), dwErr, dwType));
        }
    }

    return (dwErr == ERROR_NO_MORE_ITEMS ? ERROR_SUCCESS : dwErr);
}


/*++

System power state processing sample.

--*/
DWORD
MyProcessSystemPowerStates(
    VOID
    )
{
    WCHAR wsKeyBuff[MAX_PATH];
    DWORD dwKeyBuffLen;
    DWORD dwSubErr;
    DWORD dwErr;
    int   iKey;
    HKEY  hKey;

    // open the power manager's state keys
    //
    _stprintf(wsKeyBuff, _T("%s\\State"), PWRMGR_REG_KEY);
    dwErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                         wsKeyBuff,
                         0, 0, 
                         &hKey);

    // enumerate the subkeys
    //
    for (iKey = 0; ERROR_SUCCESS == dwErr; iKey++)
    {
        memset(&wsKeyBuff, 0, MAX_PATH);
        dwKeyBuffLen = MAX_PATH;

        dwErr = RegEnumKeyEx(hKey, 
                             iKey,
                             &wsKeyBuff[0],
                             &dwKeyBuffLen,
                             NULL, NULL, NULL, NULL);

        if (ERROR_SUCCESS == dwErr) 
        {
            HKEY hSubKey;

            // open the subkey
            //
            dwSubErr = RegOpenKeyEx(hKey, 
                                    &wsKeyBuff[0],
                                    0, 0, 
                                    &hSubKey);
            if (ERROR_SUCCESS != dwSubErr) {
                DEBUGMSG(ZONE_ERR, (TEXT("PMAPI!RegOpenKeyEx ERROR:%d\n"), dwSubErr));
                break;
            }

            // enumerate the values
            //
            dwSubErr = MyEnumRegValues(hSubKey, wsKeyBuff, dwKeyBuffLen);

            if (hSubKey)
                RegCloseKey(hSubKey);

            // subkeys name the system states, so set them...
            //
            DEBUGMSG(ZONE_TRACE, (TEXT("PMAPI!SetSystemPowerState:%s\n"), wsKeyBuff));
            dwErr = SetSystemPowerState(wsKeyBuff, 0, 0);
            if (ERROR_SUCCESS != dwErr && 
                ERROR_CANCELLED != dwErr && 
                ERROR_SET_POWER_STATE_VETOED != dwErr) 
            {
                DEBUGMSG(ZONE_ERR, (TEXT("PMAPI!*** SetSystemPowerState ERROR:%d ***\n"), dwErr));
                RegCloseKey(hSubKey);
                break;
            }
            
            DEBUGMSG(ZONE_TRACE, (TEXT("PMAPI!SetSystemPowerState:%s, POWER_FORCE\n"), wsKeyBuff));
            dwErr = SetSystemPowerState(wsKeyBuff, 0, POWER_FORCE);
            if (ERROR_SUCCESS != dwErr) {
                DEBUGMSG(ZONE_ERR, (TEXT("PMAPI!*** SetSystemPowerState ERROR:%d ***\n"), dwErr));
                RegCloseKey(hSubKey);
                break;
            }
        
        } else if (ERROR_NO_MORE_ITEMS != dwErr) {
            DEBUGMSG(ZONE_ERR, (TEXT("PMAPI!RegEnumKeyEx ERROR: %d \n"), dwErr));
        }
    }

    if (hKey)
        RegCloseKey(hKey);

    return (dwErr == ERROR_NO_MORE_ITEMS ? ERROR_SUCCESS : dwErr);
}


// Simple test app
//
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPWSTR lpCmdLine, int nCmShow)
{
    TCHAR  *argv[20];
    int     argc;
    CMD     cCmd = 0;

    MSGQUEUEOPTIONS msgOptions = {0};
    MEMORYSTATUS m1 = {0}, m2 = {0};
    DWORD dwErr;
    HANDLE hReq = NULL;
    HANDLE hNotifications;
    CEDEVICE_POWER_STATE Dx;
    HANDLE hPrev;
    HANDLE hThread;
    DWORD dwTest = 1;
    BOOL  bDone = FALSE;

    WIN32_FIND_DATA fd;
    DWORD  device;

    UNREFERENCED_PARAMETER(hInst);
    UNREFERENCED_PARAMETER(hPrevInst);
    UNREFERENCED_PARAMETER(lpCmdLine);
    UNREFERENCED_PARAMETER(nCmShow);

    DEBUGREGISTER(NULL);

    //
    // parse command line
    //
    argc = CreateArgvArgc(TEXT( "PMAPI" ), argv, lpCmdLine);
    if (argc >= 2) {
        if (!swscanf(argv[1], TEXT("%c"), &cCmd ))
            cCmd = 0;
    }

    switch (cCmd) 
    {
        case TEST_ONCE:
        case TEST_INFINITE:
        case PREMATURE_RELEASE: 
        break;

        default: 
        {
            DEBUGMSG(ZONE_ERR, (TEXT("PMAPI <Command>\n")));
            DEBUGMSG(ZONE_ERR, (TEXT("  where <Command> is one of\n")));
            DEBUGMSG(ZONE_ERR, (TEXT("    %c : Infinite test pass\n"), TEST_INFINITE));
            DEBUGMSG(ZONE_ERR, (TEXT("    %c : One-shot test pass\n"), TEST_ONCE));
            DEBUGMSG(ZONE_ERR, (TEXT("    %c : Premature exit test pass\n"), PREMATURE_RELEASE));
        } return 0;
    }

    // snap mem
    //
	GlobalMemoryStatus(&m1);
	DEBUGMSG(ZONE_TRACE, (TEXT("PMAPI!Before PM API Tests: Virtual Memory = %ld\n"), m1.dwAvailVirtual));

    //
    // create a message queue for device notifications
    //
    msgOptions.dwSize = sizeof(MSGQUEUEOPTIONS);
    msgOptions.dwFlags = 0;
    msgOptions.cbMaxMessage = QUEUE_SIZE;
    msgOptions.bReadAccess = TRUE;
    hMsgQ = CreateMsgQueue(NULL, &msgOptions);
    if (!hMsgQ) {
        dwErr = GetLastError();
        DEBUGMSG(ZONE_ERR, (TEXT("PMAPI!CreateMessageQueue ERROR:%d\n"), dwErr));
        return dwErr;
    }

    // request Power notifications
    //
    hNotifications = RequestPowerNotifications(hMsgQ, 
                                               POWER_NOTIFY_ALL);
    if (!hNotifications) {
        CloseMsgQueue(hMsgQ);
        dwErr = GetLastError();
        DEBUGMSG(ZONE_ERR, (TEXT("PMAPI!RequestPowerNotifications ERROR:%d\n"), dwErr));
        return dwErr;
    }

    // start the notify thread
    //
    hThread = CreateThread(NULL, 0, 
                           PowerNotifyThread,
                           NULL,
                           0, NULL );
    if ( !hThread ) {
        dwErr = GetLastError();
        DEBUGMSG(ZONE_ERR, (TEXT("PMAPI!CreateThread ERROR:%d\n"), dwErr ));
        return -1;
    }

    do {
        DEBUGMSG(ZONE_ERR, (TEXT("\nPMAPI!************************ BEGIN PM API Test[%d]************************\n"), dwTest));

        /////////////////////////////////////////////
        //
        // Test : set every *named* system power state
        //
        dwErr = MyProcessSystemPowerStates( );
        if (ERROR_SUCCESS != dwErr && 
            ERROR_CANCELLED != dwErr && // cancelled by user dialog
            ERROR_SET_POWER_STATE_VETOED != dwErr
            ) 
        {
            DEBUGMSG(ZONE_ERR, (TEXT("PMAPI!MyProcessSystemPowerStates ERROR.1:%d\n"), dwErr));
            break;
        }

        /////////////////////////////////////////////
        //
        // Test: SetSystemPowerState: by flags
        //
        DEBUGMSG(ZONE_TRACE, (TEXT("PMAPI!SetSystemPowerState:POWER_STATE_SUSPEND, POWER_FORCE\n")));
        dwErr = SetSystemPowerState(NULL,
            POWER_STATE_SUSPEND,
            POWER_FORCE);
        if (ERROR_SUCCESS != dwErr) {
            DEBUGMSG(ZONE_ERR, (TEXT("PMAPI!SetSystemPowerState ERROR.1:%d\n"), dwErr));
            break;
        }
       

        /////////////////////////////////////////////
        //
        // Test: SetSystemPowerState: invalid states
        //
        DEBUGMSG(ZONE_TRACE, (TEXT("PMAPI!SetSystemPowerState:abcde\n")));
        dwErr = SetSystemPowerState(L"abcde", 0, 0);
        if (ERROR_SUCCESS == dwErr) {
            DEBUGMSG(ZONE_ERR, (TEXT("PMAPI!*** SetSystemPowerState ERROR.2:%d ****\n"), dwErr));
            break;
        }

        DEBUGMSG(ZONE_TRACE, (TEXT("PMAPI!SetSystemPowerState: 123 \n")));
        dwErr = SetSystemPowerState(L" 123 ", 0, 0);
        if (ERROR_SUCCESS == dwErr) {
            DEBUGMSG(ZONE_ERR, (TEXT("PMAPI!*** SetSystemPowerState ERROR.2:%d ****\n"), dwErr));
            break;
        }

        /////////////////////////////////////////////
        //
        // Test: SetPowerRequirement: invalid parameters
        //
        dwErr = ERROR_SUCCESS;
        for (Dx = PwrDeviceUnspecified; Dx <= PwrDeviceMaximum; Dx++)
        {
            HANDLE h;
            // *INVALID* parameter
            DEBUGMSG(ZONE_TRACE, (TEXT("PMAPI!SetPowerRequirement:#$%#$\n")));
            h = SetPowerRequirement(L"#$%#$",    // *INVALID* DeviceName
	                                Dx,          // DeviceState,
	                                POWER_NAME,  // DeviceFlags
	                                NULL,
	                                0);
            if (h) {
                dwErr = GetLastError();
                DEBUGMSG(ZONE_ERR, (TEXT("PMAPI!*** SetPowerRequirement ERROR.3.1:%d ****\n"), dwErr));
                break;
            }

            // *INVALID* parameter
            DEBUGMSG(ZONE_TRACE, (TEXT("PMAPI!SetPowerRequirement:PwrDeviceMaximum\n")));
            h = SetPowerRequirement(L"DSK1:",           // DeviceName
	                                Dx,                 // DeviceState,
	                                0,                 // *INVALID* Flags
	                                NULL,
	                                0);
            if (h) {
                dwErr = GetLastError();
                DEBUGMSG(ZONE_ERR, (TEXT("PMAPI!*** SetPowerRequirement ERROR.3.2:%d ****\n"), dwErr));
                break;
            }
        }
        if (ERROR_SUCCESS != dwErr)
            break;

        /////////////////////////////////////////////
        //
        // Test: SetPowerRequirement: make sure we always get the same handle in this process
        //
        hPrev = hReq = NULL;
        for ( Dx = D0; Dx < PwrDeviceMaximum; Dx++)
        {
            DEBUGMSG(ZONE_TRACE, (TEXT("PMAPI!SetPowerRequirement:DSK1:\n")));
            hReq = SetPowerRequirement(L"DSK1:",    // DeviceName
	                                   Dx,          // DeviceState,
	                                   POWER_NAME,  // Flags
	                                   NULL,
	                                   0);
	                                   
            if (!hReq) {
                dwErr = GetLastError();
                DEBUGMSG(ZONE_ERR, (TEXT("PMAPI!*** SetPowerRequirement ERROR.3.3:%d, Dx:%d****\n"), dwErr, Dx));
                break;
            }

            if (hPrev && (hPrev != hReq)) {
                dwErr = ERROR_GEN_FAILURE;
                DEBUGMSG(ZONE_ERR, (TEXT("PMAPI!*** SetPowerRequirement ERROR.3.4:%d, hPrev:0x%x, hReq:0x%x ****\n"), dwErr, hPrev, hReq));
                break;
            }
            hPrev = hReq;
        }
        if (ERROR_SUCCESS != dwErr)
            break;
                   
        DEBUGMSG(ZONE_TRACE, (TEXT("PMAPI!ReleasePowerRequirement\n")));
        dwErr = ReleasePowerRequirement(hReq);
        if (ERROR_SUCCESS != dwErr)
            break;



        /////////////////////////////////////////////
        //
        // Test: SetPowerRequirement: on *all devices*
        //
        for (device = 0; ; device++)
        {
            memset(&fd, 0, sizeof(fd));

            if ( !GetDeviceByIndex(device, &fd) ) {
                DEBUGMSG(ZONE_TRACE, (TEXT("PMAPI!GetDeviceByIndex: no more devices:%d\n"), device));
                break;
            }

            for (Dx = D0; Dx < PwrDeviceMaximum; Dx++)
            {
                DEBUGMSG(ZONE_TRACE, (TEXT("PMAPI!SetPowerRequirement:'%s', D%d\n"), fd.cFileName, Dx));
                hReq = SetPowerRequirement(fd.cFileName,    // DeviceName
	                                       Dx,              // DeviceState,
	                                       POWER_NAME,       // Flags
	                                       NULL,
	                                       0);
                if ( !hReq ) {
                    dwErr = GetLastError();
                    DEBUGMSG(ZONE_TRACE, (TEXT("PMAPI!*** SetPowerRequirement Device:'%s', Dx:%d, ERROR.4:%d ****\n"), 
                                fd.cFileName, Dx, dwErr));                    
                    if (fd.cFileName[0] != 0) // NULL name?
                        break;
                    else 
                        dwErr = ERROR_SUCCESS;
                }
            }
            if (ERROR_SUCCESS != dwErr)
                break;
            
            DEBUGMSG(ZONE_TRACE, (TEXT("PMAPI!ReleasePowerRequirement\n")));
            dwErr = ReleasePowerRequirement(hReq);
            if (ERROR_SUCCESS != dwErr) {
                DEBUGMSG(ZONE_TRACE, (TEXT("PMAPI!ReleasePowerRequirement ERROR:%d\n"), dwErr));
                if (hReq)
                    break;
                else 
                    dwErr = ERROR_SUCCESS;
            }
        }
        if (ERROR_SUCCESS != dwErr)
            break;


        /////////////////////////////////////////////
        //
        // Test : simulate DevicePowerNotify on all devices
        //
        for (device = 0; ; device++)
        {
            memset(&fd, 0, sizeof(fd));

            if ( !GetDeviceByIndex(device, &fd) ) {
                DEBUGMSG(ZONE_TRACE, (TEXT("PMAPI!GetDeviceByIndex: no more devices:%d\n"), device));
                break;
            }

            for (Dx = D0; Dx < PwrDeviceMaximum; Dx++) 
            {
                dwErr = DevicePowerNotify(fd.cFileName,              // DeviceName
	                                      Dx,                        // DeviceState,
	                                      POWER_NAME                 // Flags
	                                      );
                if ( ERROR_SUCCESS != dwErr ) {
                    // this error code was propogated from the named device, so don't abort
                    DEBUGMSG(ZONE_TRACE, (TEXT("PMAPI!*** DevicePowerNotify Device:'%s', Dx:%d, ERROR:%d ****\n"), 
                                fd.cFileName, Dx, dwErr));
                }
            }
        }
        dwErr = ERROR_SUCCESS;


        /////////////////////////////////////////////
        //
        // Test: set device requirement on *all devices*, then adjust the system power level
        //

        // ....


        /////////////////////////////////////////////
        //
        // Test: set device requirement on *all* devices, then exit prematurely
        //
        for (device = 0; ;device++)
        {
            memset(&fd, 0, sizeof(fd));

            if ( !GetDeviceByIndex(device, &fd) ) {
                DEBUGMSG(ZONE_TRACE, (TEXT("PMAPI!GetDeviceByIndex: no more devices:%d\n"), device));
                break;
            }

            for (Dx = D0; Dx < PwrDeviceMaximum; Dx++) 
            {
                DEBUGMSG(ZONE_TRACE, (TEXT("PMAPI!SetPowerRequirement:'%s'\n"), fd.cFileName));
                hReq = SetPowerRequirement(fd.cFileName,    // DeviceName
	                                       Dx,              // DeviceState,
	                                       POWER_NAME,      // Flags
	                                       0,
	                                       0);
                if ( !hReq ) {
                    DEBUGMSG(ZONE_TRACE, (TEXT("PMAPI!*** SetPowerRequirement on Device:'%s', Dx:%d, ERROR.0:%d ****\n"), 
                                fd.cFileName, Dx, GetLastError()));
                    if (fd.cFileName[0] != 0) // NULL name?
                        break;
                    else 
                        dwErr = ERROR_SUCCESS;
                }
                // drop them all on the floor to see if PM will clean it up
            }
        }

        switch(cCmd) 
        {
            case PREMATURE_RELEASE:
                exit(0);
            
            case TEST_INFINITE:
                Sleep(500);
                break;

            default:
                bDone = TRUE;
                break;
        }

        DEBUGMSG(ZONE_ERR, (TEXT("\nPMAPI!************************ END PM API Test[%d] ************************\n"), dwTest++));

    } while (!bDone);


    DEBUGMSG(ZONE_TRACE, (TEXT("PMAPI!StopPowerNotifications\n")));
    if ( !StopPowerNotifications(hNotifications) ) {
        DEBUGMSG(ZONE_ERR, (TEXT("PMAPI!StopNotifications ERROR:%d\n"), GetLastError()));
    }
    CloseMsgQueue(hMsgQ);


    // snap mem
    //
    GlobalMemoryStatus(&m2);
    DEBUGMSG(ZONE_TRACE, (TEXT("PMAPI!After PM API Tests: Virtual Memory = %ld\n"), m2.dwAvailVirtual));

    if ((m2.dwAvailVirtual < m1.dwAvailVirtual)) {
        DEBUGMSG(ZONE_TRACE, (TEXT("PMAPI!\n\n*** PM API Leaked: Physical Memory = %ld, Virtual Memory = %ld ***\n"), 
                        (m1.dwAvailPhys - m2.dwAvailPhys), (m1.dwAvailVirtual - m2.dwAvailVirtual)));
    }

    if (ERROR_SUCCESS != dwErr) {
        DEBUGMSG(ZONE_ERR, (TEXT("\n\n*** PMAPI TEST FAILED:%d ****\n\n"), dwErr));
    } else {
        DEBUGMSG(ZONE_ERR, (TEXT("\n\n*** PMAPI TEST PASSED ****\n\n")));
    }

    return 1; 
}


int
GetPriority(
    VOID
    )
{
    return 251;     // THREAD_PRIORITY_NORMAL
}


DWORD WINAPI 
PowerNotifyThread(
    LPVOID Context
    )
{
    DWORD dwErr, dwFlags = 0, dwCount = 0;
    DWORD dwPri = 0;
        
    UCHAR buf[QUEUE_SIZE];
    int iBytesInQueue;

    const int ci = sizeof(POWER_BROADCAST);

    dwPri = GetPriority();
    if ( !CeSetThreadPriority(GetCurrentThread(), dwPri)) {
        dwErr = GetLastError();
        DEBUGMSG(ZONE_ERR, (TEXT("PMAPI!CeSetThreadPriority ERROR:%d\n"), dwErr));
        ExitThread(dwErr);
        return dwErr;       
    }

    do {
        iBytesInQueue = 0;
        memset(&buf, 0, QUEUE_SIZE);

        // Block on our message queue.
        // This thread runs when the power manager writes a notification into the queue.
        if ( !ReadMsgQueue(hMsgQ,
                           &buf,
                           QUEUE_SIZE,
                           &iBytesInQueue,
                           INFINITE,    // Timeout
                           &dwFlags))
        {
            dwErr = GetLastError();
            DEBUGMSG(ZONE_ERR, (TEXT("PMAPI!ReadMsgQueue: ERROR:%d\n"), dwErr));
            break;
        } else {
            //
            // process power notifications
            //
            PPOWER_BROADCAST pB = (PPOWER_BROADCAST)&buf;

            while (iBytesInQueue > 0 && iBytesInQueue > ci) 
            {
                DEBUGMSG(ZONE_THREAD, (TEXT("PMAPI!*** Power Notification @ Tick:%u, Count:%d, Pri:%d***\n"), 
                            GetTickCount(), dwCount++, CeGetThreadPriority(GetCurrentThread())));
                DEBUGMSG(ZONE_THREAD, (TEXT("PMAPI!\tMessage: 0x%x\n"), pB->Message));
                DEBUGMSG(ZONE_THREAD, (TEXT("PMAPI!\tFlags: 0x%x\n"), pB->Flags));
                DEBUGMSG(ZONE_THREAD, (TEXT("PMAPI!\tdwLen: %d\n"), pB->Length));
                DEBUGMSG(ZONE_THREAD, (TEXT("PMAPI!\tSystemPowerState: '%s'\n"), pB->SystemPowerState));

                switch (pB->Message) 
                {
                    case PBT_TRANSITION:
                        DEBUGMSG(ZONE_THREAD, (TEXT("PMAPI!\tPBT_TRANSITION\n")));
                        switch (POWER_STATE(pB->Flags)) {
                            case POWER_STATE_ON:
                                DEBUGMSG(ZONE_THREAD, (TEXT("PMAPI!\tPOWER_STATE_ON\n")));
                                break;
                            case POWER_STATE_OFF:
                                DEBUGMSG(ZONE_THREAD, (TEXT("PMAPI!\tPOWER_STATE_OFF\n")));
                                break;
                            case POWER_STATE_CRITICAL:
                                DEBUGMSG(ZONE_THREAD, (TEXT("PMAPI!\tPOWER_STATE_CRITICAL\n")));
                                break;
                            case POWER_STATE_BOOT:
                                DEBUGMSG(ZONE_THREAD, (TEXT("PMAPI!\tPOWER_STATE_BOOT\n")));
                                break;
                            case POWER_STATE_IDLE:
                                DEBUGMSG(ZONE_THREAD, (TEXT("PMAPI!\tPOWER_STATE_IDLE\n")));
                                break;
                            case POWER_STATE_SUSPEND:
                                DEBUGMSG(ZONE_THREAD, (TEXT("PMAPI!\tPOWER_STATE_SUSPEND\n")));
                                break;
                            case POWER_STATE_RESET:
                                DEBUGMSG(ZONE_THREAD, (TEXT("PMAPI!\tPOWER_STATE_RESET\n")));
                                break;
                            default:
                                DEBUGMSG(ZONE_THREAD,(TEXT("PMAPI!\tUnknown Power State:0x%x\n"),pB->Flags));
                                ASSERT(0);
                                break;
                        }
                        break;

                    case PBT_RESUME:
                        DEBUGMSG(ZONE_THREAD, (TEXT("PMAPI!\tPBT_RESUME\n")));
                        break;

                    case PBT_POWERSTATUSCHANGE:
                        DEBUGMSG(ZONE_THREAD, (TEXT("PMAPI!\tPBT_POWERSTATUSCHANGE\n")));
                        break;

                    default:
                        DEBUGMSG(ZONE_THREAD, (TEXT("PMAPI!\tInvalid Message:%d\n"), pB->Message));
                        ASSERT(0);
                        break;
                }
                
                DEBUGMSG(ZONE_THREAD, (TEXT("PMAPI!***********************\n")));

                iBytesInQueue -= ci + pB->Length;
                pB += ci + pB->Length;
            }
        }

    } while (1);
    
    ExitThread(ERROR_SUCCESS);  
    return ERROR_SUCCESS;
}

// EOF







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章