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

📄 pmutils.cpp

📁 此代码为WCE5.0下电源管理的源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//
// 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) {
        PMLOGMSG(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;
            PMLOGMSG(ZONE_REGISTRY, (_T("%s: priority for '%s' is %d\r\n"),
                pszFname, pszValue, dwValue));
            fOk = TRUE;
        }

        // close the key
        RegCloseKey(hkPm);
    }

    PMLOGMSG(!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) {
        PMLOGMSG(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

#ifdef DEBUG
    PMLOGMSG(ZONE_ALLOC, (_T("%s: alloc %d bytes returned 0x%08x (%d total objects allocated)\r\n"), 
        pszFname, dwSize, pvRet, glTotalObjects));
#else   // DEBUG
    PMLOGMSG(ZONE_ALLOC, (_T("%s: alloc %d bytes returned 0x%08x\r\n"), 
        pszFname, dwSize, pvRet));
#endif  // DEBUG
    return pvRet;
}

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

    PMLOGMSG(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) {
        PMLOGMSG(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;
}

// ------------------------ DEVICE ID MANAGEMENT ------------------------

static BOOL 
HexStringToDword(LPCWSTR FAR& lpsz, DWORD FAR& Value,
                 int cDigits, WCHAR chDelim)
{
    int Count;
    
    Value = 0;
    for (Count = 0; Count < cDigits; Count++, lpsz++)
    {
        if (*lpsz >= '0' && *lpsz <= '9')
            Value = (Value << 4) + *lpsz - '0';
        else if (*lpsz >= 'A' && *lpsz <= 'F')
            Value = (Value << 4) + *lpsz - 'A' + 10;
        else if (*lpsz >= 'a' && *lpsz <= 'f')
            Value = (Value << 4) + *lpsz - 'a' + 10;
        else
            return(FALSE);
    }
    
    if (chDelim != 0)
        return *lpsz++ == chDelim;
    else
        return TRUE;
}


static BOOL 
wUUIDFromString(LPCWSTR lpsz, LPGUID pguid)
{
    DWORD dw;
    
    if (!HexStringToDword(lpsz, pguid->Data1, sizeof(DWORD)*2, '-'))
        return FALSE;
    
    if (!HexStringToDword(lpsz, dw, sizeof(WORD)*2, '-'))
        return FALSE;
    
    pguid->Data2 = (WORD)dw;
    
    if (!HexStringToDword(lpsz, dw, sizeof(WORD)*2, '-'))
        return FALSE;
    
    pguid->Data3 = (WORD)dw;
    
    if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
        return FALSE;
    
    pguid->Data4[0] = (BYTE)dw;
    
    if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, '-'))
        return FALSE;
    
    pguid->Data4[1] = (BYTE)dw;
    
    if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
        return FALSE;
    
    pguid->Data4[2] = (BYTE)dw;
    
    if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
        return FALSE;
    
    pguid->Data4[3] = (BYTE)dw;
    
    if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
        return FALSE;
    
    pguid->Data4[4] = (BYTE)dw;
    
    if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
        return FALSE;
    
    pguid->Data4[5] = (BYTE)dw;
    
    if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
        return FALSE;
    
    pguid->Data4[6] = (BYTE)dw;
    if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
        return FALSE;
    
    pguid->Data4[7] = (BYTE)dw;
    
    return TRUE;
}

static BOOL 
GUIDFromString(LPCWSTR lpsz, LPGUID pguid)
{
    if (*lpsz++ != '{' )
        return FALSE;
    
    if(wUUIDFromString(lpsz, pguid) != TRUE)
        return FALSE;
    
    lpsz +=36;
    
    if (*lpsz++ != '}' )
        return FALSE;
    
    return TRUE;
}

// this routine converts a text string to a GUID if possible.
BOOL 
ConvertStringToGuid (LPCTSTR pszGuid, GUID *pGuid)
{
    BOOL fOk = FALSE;
    SETFNAME(_T("ConvertStringToGuid"));

    DEBUGCHK(pGuid != NULL && pszGuid != NULL);
    __try {
        if (! GUIDFromString(pszGuid, pGuid)) {
            PMLOGMSG(ZONE_WARN, (_T("%s: couldn't parse '%s'\r\n"), pszFname,
                pszGuid));
        }
        fOk = TRUE;
    }
    __except(EXCEPTION_EXECUTE_HANDLER) {
        PMLOGMSG(ZONE_WARN, (_T("%s: error parsing guid\r\n"), pszFname));
    }

    return fOk;
}

// This routine returns the number of bytes that would need to be allocated to hold
// a copy of the device ID being passed in as a parameter.  It returns zero if there
// is an error OR if the device id pointer is NULL.
DWORD
DeviceIdSize(PDEVICEID pId)
{
    DWORD dwSize;
    SETFNAME(_T("DeviceIdSize"));

    if(pId != NULL) {
        // calculate the amount of memory to allocate
        __try {
            dwSize = sizeof(*pId);
            if(pId->pszName != NULL) {
                dwSize += (_tcslen(pId->pszName) + 1) * sizeof(pId->pszName[0]);
            }
            if(pId->pGuid != NULL) {
                dwSize += sizeof(GUID);
            }
        }
        __except(EXCEPTION_EXECUTE_HANDLER) {
            PMLOGMSG(ZONE_WARN, (_T("%s: exception calculating size\r\n"), pszFname));
            dwSize = 0;;
        }
    } else {
        dwSize = 0;
    }

    return dwSize;
}

// This routine clones a source device ID into a pre-allocated buffer.  The 
// pre-allocation enables callers to reduce the number of heap allocations
// they need to make when embedding device IDs into larger structures.
// This routine returns pIdDst, or NULL in case of error.  Errors include
// insufficient buffer size or exceptions while copying.
PDEVICEID
DeviceIdCloneIntoBuffer(PDEVICEID pIdSrc, PDEVICEID pIdDst, DWORD cbDst)
{
    DWORD dwSize;
    SETFNAME(_T("DeviceIdCloneIntoBuffer"));

    PREFAST_DEBUGCHK(pIdSrc != NULL);
    DEBUGCHK(pIdSrc->pGuid != NULL || pIdSrc->pszName != NULL);
    PREFAST_DEBUGCHK(pIdDst != NULL);
    DEBUGCHK(cbDst >= sizeof(DEVICEID));

    // make sure we have enough room
    dwSize = DeviceIdSize(pIdSrc);
    if(cbDst < dwSize) {
        PMLOGMSG(ZONE_WARN, 
            (_T("%s: destination buffer size %d too small, %d bytes needed\r\n"),
            pszFname, cbDst, dwSize));
        pIdDst = NULL;
    } else {
        memset(pIdDst, 0, dwSize);
        pIdDst->pGuid = NULL;

⌨️ 快捷键说明

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