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

📄 stubutils.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.
//

//
// This modules contains various utility routines for creating, deleting
// and accessing power manager data.
//

#include <pmimpl.h>
#include <msgqueue.h>
#include <nkintr.h>

#ifdef DEBUG
// turns on some memory garbling code -- adds overhead but hopefully helps catch bugs
#define DEBUGALLOC
#endif  // DEBUG


// ------------------------ REGISTRY FUNCTIONS ------------------------

// This routine reads data from the registry and verifies that it's
// of the proper type.  It returns ERROR_SUCCESS if the data can be
// read and is the right type or a registry error if it can't be
// read.  If the data is the wrong type, this routine returns
// ERROR_INVALID_DATA.
DWORD
RegQueryTypedValue(HKEY hk, LPCWSTR pszValue, PVOID pvData, 
                   LPDWORD pdwSize, DWORD dwType)
{
    DWORD dwActualType;
    SETFNAME(_T("RegQueryTypedValue"));

    DWORD dwStatus = RegQueryValueEx(hk, pszValue, NULL, &dwActualType, 
        (PBYTE) pvData, pdwSize);
    if(dwStatus == ERROR_SUCCESS && dwActualType != dwType) {
        DEBUGMSG(ZONE_WARN, (_T("%s: wrong type for '%s'\r\n"),
            pszFname, pszValue));
        dwStatus = ERROR_INVALID_DATA;
    }

    return dwStatus;
}

BOOL
GetPMThreadPriority(LPCTSTR pszValue, LPINT piThreadPriority)
{
    BOOL fOk = FALSE;
    HKEY hkPm = NULL;
    DWORD dwStatus;
    SETFNAME(_T("GetPMThreadPriority"));

    // open the PM key
    dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, PWRMGR_REG_KEY, 0, 0, &hkPm);
    if(dwStatus == ERROR_SUCCESS) {
        DWORD dwValue;
        DWORD dwSize = sizeof(dwValue);

        // read the requested value
        dwStatus = RegQueryTypedValue(hkPm, pszValue, &dwValue, &dwSize, REG_DWORD);
        if(dwStatus == ERROR_SUCCESS) {
            *piThreadPriority = (INT) dwValue;
            DEBUGMSG(ZONE_REGISTRY, (_T("%s: priority for '%s' is %d\r\n"),
                pszFname, pszValue, dwValue));
            fOk = TRUE;
        }

        // close the key
        RegCloseKey(hkPm);
    }

    DEBUGMSG(!fOk && ZONE_REGISTRY, (_T("%s: no setting for '%s'\r\n"),
        pszFname, pszValue));

    return fOk;
}

// ------------------------ SERIALIZATION ------------------------

// serialize access to PM list variables and structure members
VOID
PmLock(VOID)
{
    EnterCriticalSection(&gcsPowerManager);
}

// release synchronization objects obtained with PmLock()
VOID
PmUnlock(VOID)
{
    LeaveCriticalSection(&gcsPowerManager);
}

// serialize access to appliation APIs that cause device updates
VOID
PmEnterUpdate(VOID)
{
    EnterCriticalSection(&gcsDeviceUpdateAPIs);
}

// release synchronization objects obtained with PmEnterUpdate()
VOID
PmLeaveUpdate(VOID)
{
    LeaveCriticalSection(&gcsDeviceUpdateAPIs);
}

// ------------------------ MEMORY STATE MANAGEMENT ------------------------

#define HEAPSIGNATURE       0xFA124301      // randomly chosen number
#define HEAPHEADERSIZE      (4 * sizeof(DWORD))

#ifdef DEBUG
// debug globals
LONG glTotalObjects = 0;
#endif  // DEBUG

// this routine allocates memory and returns a pointer to it, or returns
// NULL.
PVOID
PmAlloc(DWORD dwSize)
{
    SETFNAME(_T("PmAlloc"));

    DEBUGCHK(dwSize != 0);

#ifdef DEBUGALLOC
    // prepend a header so we can track post-free accesses of the memory
    dwSize += HEAPHEADERSIZE;
#endif  // DEBUGALLOC

    PVOID pvRet = HeapAlloc(ghPmHeap, 0, dwSize);
    if(pvRet == NULL) {
        DEBUGMSG(ZONE_WARN, (_T("%s: HeapAlloc(%d) failed %d\r\n"), pszFname,
            dwSize, GetLastError()));
    }
#ifdef DEBUG
    else {
        InterlockedIncrement(&glTotalObjects);
    }
#endif  // DEBUG

#ifdef DEBUGALLOC
    // fill memory with a diagnostic pattern for debugging
    if(pvRet != NULL) {
        memset(pvRet, 0xAA, dwSize);
        PDWORD pdwRet = (PDWORD) pvRet;
        pdwRet[0] = HEAPSIGNATURE;  // record a signature
        pdwRet[1] = dwSize;         // and the real size of the buffer
        pvRet = &pdwRet[HEAPHEADERSIZE / sizeof(DWORD)]; // return a pointer to a buffer of the requested size
    }
#endif  // DEBUGALLOC

    DEBUGMSG(ZONE_ALLOC, (_T("%s: alloc %d bytes returned 0x%08x (%d total objects allocated)\r\n"), 
        pszFname, dwSize, pvRet, glTotalObjects));

    return pvRet;
}

// this routine frees memory allocated with PmAlloc()
BOOL
PmFree(PVOID pvMemory)
{
    SETFNAME(_T("PmFree"));

    DEBUGMSG(ZONE_ALLOC, (_T("%s: freeing 0x%08x\r\n"), pszFname, pvMemory));

    DEBUGCHK(pvMemory != NULL);

#ifdef DEBUGALLOC
    // fill 
    if(pvMemory != NULL) {
        PDWORD pdwMemory = (PDWORD) ((DWORD) pvMemory - HEAPHEADERSIZE);
        DEBUGCHK(pdwMemory[0] == HEAPSIGNATURE && pdwMemory[1] > HEAPHEADERSIZE);
        memset(pdwMemory, 0xDD, pdwMemory[1]);
        pvMemory = pdwMemory;
    }
#endif  // DEBUGALLOC

    BOOL fOk = HeapFree(ghPmHeap, 0, pvMemory);
    if(!fOk) {
        DEBUGMSG(ZONE_WARN, (_T("%s: HeapFree(0x%08x) failed %d\r\n"), pszFname,
            pvMemory, GetLastError()));
    }
#ifdef DEBUG
    else {
        InterlockedDecrement(&glTotalObjects);
        DEBUGCHK(glTotalObjects >= 0);
    }
#endif  // DEBUG
    return fOk;
}

// ------------------------ POWER NOTIFICATION MANAGEMENT ----------

// This routine creates a data structure describing a power notification.
// It returns a pointer to the structure, or NULL if there's an
// error.
PPOWER_NOTIFICATION
PowerNotificationCreate(HANDLE hMsgQ, HANDLE hOwner)
{
    SETFNAME(_T("PowerNotificationCreate"));

    // allocate resources
    PPOWER_NOTIFICATION ppn = (PPOWER_NOTIFICATION) PmAlloc(sizeof(*ppn));
    if(ppn != NULL ) {
        // initialize the structure
        memset(ppn, 0, sizeof(*ppn));
        ppn->hOwner = hOwner;
        ppn->pNext = NULL;
        ppn->pPrev = NULL;

        // now try to open the message queue
        MSGQUEUEOPTIONS msgopts;
        memset(&msgopts, 0, sizeof(msgopts));
        msgopts.dwSize = sizeof(MSGQUEUEOPTIONS);
        msgopts.bReadAccess = FALSE;
        ppn->hMsgQ = OpenMsgQueue(hOwner, hMsgQ, &msgopts);
        if(ppn->hMsgQ == NULL) {
            DEBUGMSG(ZONE_WARN, 
                (_T("%s: OpenMsgQueue() failed %d (owner 0x%08x, source q 0x%08x)\r\n"),
                pszFname, GetLastError(), hOwner, hMsgQ));
            PmFree(ppn);
            ppn = NULL;
        }
    }

    DEBUGMSG(ppn == NULL && ZONE_WARN, (_T("%s: couldn't create structure\r\n"), pszFname));
    return ppn;
}

// this routine deallocates a device state structure.  It returns TRUE if 
// successful, FALSE otherwise.
BOOL
PowerNotificationDestroy(PPOWER_NOTIFICATION ppn)
{
    BOOL fOk = TRUE;

    if(ppn != NULL) {
        if(ppn->hMsgQ != NULL) CloseMsgQueue(ppn->hMsgQ);
        PmFree(ppn);
    }

    return fOk;
}

// This routine adds a power notification to a list.
BOOL
PowerNotificationAddList(PPPOWER_NOTIFICATION ppListHead, PPOWER_NOTIFICATION ppn)
{
    BOOL fOk = TRUE;

    PREFAST_DEBUGCHK(ppListHead != NULL);
    PREFAST_DEBUGCHK(ppn != NULL);
    DEBUGCHK(ppn->pNext == NULL && ppn->pPrev == NULL);
    DEBUGCHK(ppListHead != NULL);

    // put the new device at the head of the list
    PMLOCK();
    ppn->pNext = *ppListHead;
    ppn->pPrev = NULL;
    if(*ppListHead != NULL) {
        (*ppListHead)->pPrev = ppn;
    }
    *ppListHead = ppn;
    PMUNLOCK();

    return fOk;
}

// this routine removes a power notification from a list and deletes it.
BOOL
PowerNotificationRemList(PPPOWER_NOTIFICATION ppListHead, PPOWER_NOTIFICATION ppn)
{
    BOOL fOk = TRUE;

    PREFAST_DEBUGCHK(ppListHead != NULL);

    PMLOCK();

    // are we at the head of the list?
    if(ppn->pPrev != NULL) {
        ppn->pPrev->pNext = ppn->pNext;
    } else {
        // not that if pNext == NULL && pPrev == NULL we are the only list
        // member and the assignment to the list head will set it to NULL (meaning
        // empty).
        if(ppn->pNext != NULL) {
            ppn->pNext->pPrev = NULL;
        }
        *ppListHead = ppn->pNext;
    }
    
    // are we at the tail of the list?
    if(ppn->pNext != NULL) {
        ppn->pNext->pPrev = ppn->pPrev;
    } else {
        if(ppn->pPrev != NULL) {
            ppn->pPrev->pNext = NULL;
        }
    }

    // clear list pointers
    ppn->pNext = NULL;
    ppn->pPrev = NULL;

    // delete the structure and its members
    PowerNotificationDestroy(ppn);
        
    PMUNLOCK();

    return fOk;
}

⌨️ 快捷键说明

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