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

📄 pmutils.cpp

📁 此代码为WCE5.0下电源管理的源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        pIdDst->pszName = NULL;
        __try {
            // copy class field if present
            DWORD dwNameOffset = sizeof(*pIdDst);
            
            if(pIdSrc->pGuid != NULL) {
                LPGUID pGuid = (LPGUID) ((LPBYTE) pIdDst + sizeof(*pIdDst));
                *pGuid = *pIdSrc->pGuid;
                pIdDst->pGuid = pGuid;
                dwNameOffset += sizeof(GUID);
            }

            // copy name field if present
            if(pIdSrc->pszName != NULL) {
                LPTSTR pszName = (LPTSTR) ((LPBYTE) pIdDst + dwNameOffset);
                _tcscpy(pszName, pIdSrc->pszName);
                pIdDst->pszName = pszName;
            }            
        }
        __except(EXCEPTION_EXECUTE_HANDLER) {
            PMLOGMSG(ZONE_WARN, (_T("%s: exception during member copy\r\n"), 
                pszFname));
            pIdDst = NULL;
        }
    }

    return pIdDst;
}

// This routine creates a copy of a device id and returns its pointer.  If
// there's a problem it returns NULL.
PDEVICEID
DeviceIdClone(PDEVICEID pId)
{
    PDEVICEID pIdClone;
    DWORD dwSize;
    SETFNAME(_T("DeviceIdClone"));

    DEBUGCHK(pId != NULL);

    // calculate the amount of memory to allocate
    dwSize = DeviceIdSize(pId);
    if(dwSize != 0) {
        pIdClone = (PDEVICEID) PmAlloc(dwSize);
    } else {
        pIdClone = NULL;
    }

    // copy data into the buffer
    if(pIdClone != NULL) {
        PDEVICEID pIdTmp = DeviceIdCloneIntoBuffer(pId, pIdClone, dwSize);
        if(pIdTmp == NULL) {
            PmFree(pIdClone);
            pIdClone = NULL;
        }
    }

    DEBUGCHK(pIdClone == NULL || pIdClone->pGuid != NULL || pIdClone->pszName != NULL);

    return pIdClone;
}

// This routine parses a device name string and returns a pointer to an
// allocated device ID.  The caller is responsible for freeing this pointer
// when they are done with it.  If the name cannot be parsed, this routine
// returns NULL.
PDEVICEID
DeviceIdParseNameString(LPCTSTR pszDevName, DWORD dwFlags)
{
    GUID idClass;
    LPCTSTR pszName = pszDevName;
    PDEVICEID pdi = NULL;
    DEVICEID di;
    SETFNAME(_T("DeviceIdParseNameString"));

    // sanity check the parameters
    PREFAST_DEBUGCHK(pszName != NULL);
    if((dwFlags & POWER_NAME) == 0) {
        PMLOGMSG(ZONE_WARN, 
            (_T("%s: don't know how to parse name without POWER_NAME flag\r\n"), 
            pszFname));
        return NULL;
    }

    // is the name prefixed with a guid?
    __try {
        BOOL fOk = TRUE;
        if(*pszName == '{') {
            if(!ConvertStringToGuid(pszName, &idClass)) {
                // indicate an error later
                pszName = NULL;
            } else {
                // skip the guid, we are guaranteed to find the
                // closing brace because the guid parsed ok.
                while(*pszName != '}' && *pszName != 0) {
                    pszName++;
                }

                // skip the trailing curly-brace and backslash
                if(*pszName != '}') {
                    fOk = FALSE;
                } else {
                    pszName++;      // go to the char after the close brace
                    if(*pszName != _T('\\')) {
                        fOk = FALSE;
                    } else {
                        pszName++;
                    }
                }
            }
        } else {
            // use the default device class
            idClass = idGenericPMDeviceClass;
        }
        
        // do we have a name?
        if(fOk && *pszName != 0) {
            DWORD dwLen;
            DWORD cchName;

            // yes, save it and convert to lower case
            di.pGuid = &idClass;
            cchName = _tcslen(pszName);
            dwLen = (cchName + 1) * sizeof(*pszName);
            __try {
                DWORD dwIndex;
                LPTSTR pszTempName = (LPTSTR) _alloca(dwLen);
                for(dwIndex = 0; dwIndex < cchName; dwIndex++) {
                    pszTempName[dwIndex] = _totlower(pszName[dwIndex]);
                }
                pszTempName[cchName] = 0;
                di.pszName = pszTempName;
            } 
            __except(EXCEPTION_EXECUTE_HANDLER) {
                di.pszName = NULL;
            }
            if(di.pszName != NULL) {
                pdi = DeviceIdClone(&di);
            }
        }
    }
    __except(EXCEPTION_EXECUTE_HANDLER) {
        PMLOGMSG(ZONE_WARN, (_T("%s: exception parsing name\r\n"), pszFname));
    }

    PMLOGMSG(pdi == NULL && ZONE_WARN, (_T("%s: returning 0x%08x\r\n"), pszFname, pdi));
    return pdi;
}
    
// This routine deallocates a device ID that was created with DeviceIdClone().
// Do not call this routine on a device ID that may have statically allocated
// members.
VOID
DeviceIdDestroy(PDEVICEID pId)
{
    if(pId) {
        PmFree(pId);
    }
}

// This routine returns TRUE if two device IDs match exactly, FALSE otherwise.
// Note that exact matches are expected to be case sensitive, so "FOO1:" will
// not match "foo1:".
BOOL
DeviceIdsAreEqual(PDEVICEID pId1, PDEVICEID pId2)
{
    BOOL fEqual = TRUE;

    PREFAST_DEBUGCHK(pId1 != NULL);
    PREFAST_DEBUGCHK(pId2 != NULL);
    // check name strings first
    if(pId1->pszName == NULL) {
        if(pId2->pszName != NULL) {
            fEqual = FALSE;
        }
    } else {
        if(pId2->pszName == NULL || _tcscmp(pId1->pszName, pId2->pszName) != 0) {
            fEqual = FALSE;
        }
    }

    // check guid values
    if(fEqual == TRUE) {
        if(pId1->pGuid == NULL) {
            if(pId2->pGuid != NULL) {
                fEqual = FALSE;
            }
        } else {
            if(pId2->pGuid == NULL || *pId1->pGuid != *pId2->pGuid) {
                fEqual = FALSE;
            }
        }
    }

    return fEqual;
}

// ------------------------ DEVICE STATE MANAGEMENT ------------------------

// this routine creates a data structure describing a device.  Its initial
// reference count is one.
PDEVICE_STATE
DeviceStateCreate(LPCTSTR pszName)
{
    BOOL fOk = FALSE;
    PDEVICE_STATE pds = NULL;
    SETFNAME(_T("DeviceStateCreate"));
    
    PREFAST_DEBUGCHK(pszName != NULL);

    __try {
        DWORD dwSize = sizeof(*pds) + ((_tcslen(pszName) + 1) * sizeof(pszName[0]));
        pds = (PDEVICE_STATE) PmAlloc(dwSize);
        if(pds != NULL) {
            LPTSTR pszNameCopy = (LPTSTR) ((LPBYTE) pds + sizeof(*pds));
            memset(pds, 0, sizeof(*pds));
            _tcscpy(pszNameCopy, pszName);
            pds->pszName = pszNameCopy;
            pds->curDx = D0;
            pds->floorDx = PwrDeviceUnspecified;
            pds->ceilingDx = PwrDeviceUnspecified;
            pds->setDx = PwrDeviceUnspecified;
            pds->lastReqDx = D0;
            pds->actualDx = D0;
            pds->pendingDx = PwrDeviceUnspecified;
            pds->dwNumPending = 0;
            pds->pParent = NULL;
            pds->dwRefCount = 1;
            pds->hDevice = INVALID_HANDLE_VALUE;
            pds->pListHead = NULL;
            pds->pNext = NULL;
            pds->pPrev = NULL;
            PMLOGMSG(ZONE_REFCNT, (_T("%s: created 0x%08x (name '%s'), refcnt is %d\r\n"),
                pszFname, pds, pszName, pds->dwRefCount));
            fOk = TRUE;
        }
    }
    __except(EXCEPTION_EXECUTE_HANDLER) {
        PMLOGMSG(ZONE_WARN, (_T("%s: exception initializing structure\r\n"), pszFname));
    }

    if(!fOk) {
        if(pds != NULL) {
            PmFree(pds);
            pds = NULL;
        }
    }

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

// this routine deallocates a device state structure.  It returns TRUE if 
// successful, FALSE otherwise.
BOOL
DeviceStateDestroy(PDEVICE_STATE pds)
{
    BOOL fOk = TRUE;
    SETFNAME(_T("DeviceStateDestroy"));

    PMLOGMSG(ZONE_REFCNT, (_T("%s: deleting 0x%08x\r\n"), pszFname, pds));
    if(pds != NULL) {
        if(pds->pParent != NULL) DeviceStateDecRef(pds->pParent);
        if(pds->hDevice != INVALID_HANDLE_VALUE) {
            PREFAST_DEBUGCHK(pds->pInterface != NULL);
            pds->pInterface->pfnCloseDevice(pds->hDevice);
        }
        PmFree(pds);
    }

    return fOk;
}

// this routine updates a device's reference count
VOID
DeviceStateAddRef(PDEVICE_STATE pds)
{
    SETFNAME(_T("DeviceStateAddRef"));

    PREFAST_DEBUGCHK(pds != NULL);

    PMLOCK();
    pds->dwRefCount++;
    PMLOGMSG(ZONE_REFCNT, (_T("%s: refcnt for 0x%08x set to %d\r\n"), pszFname,
        pds, pds->dwRefCount));
    PMUNLOCK();
}

// this routine decrements a device's reference count and frees the device's
// state if the reference count goes to zero.
VOID
DeviceStateDecRef(PDEVICE_STATE pds)
{
    BOOL fDestroy = FALSE;
    SETFNAME(_T("DeviceStateDecRef"));

    PREFAST_DEBUGCHK(pds != NULL);

    PMLOCK();
    DEBUGCHK(pds->dwRefCount > 0);
    pds->dwRefCount--;
    PMLOGMSG(ZONE_REFCNT, (_T("%s: refcnt for 0x%08x set to %d\r\n"), pszFname,
        pds, pds->dwRefCount));
    if(pds->dwRefCount == 0) {
        DEBUGCHK(pds->pListHead == NULL && pds->pNext == NULL && pds->pPrev == NULL);
        fDestroy = TRUE;
    }
    PMUNLOCK();

    // is it time to get rid of the device?
    if(fDestroy) {
        DeviceStateDestroy(pds);
    }
}

// this routine adds a device state structure to a list and increments its
// reference count.  It returns TRUE if successful, FALSE otherwise.
BOOL
DeviceStateAddList(PDEVICE_LIST pdl, PDEVICE_STATE pdsDevice)
{
    BOOL fOk = TRUE;
    SETFNAME(_T("DeviceStateAddList"));

    PREFAST_DEBUGCHK(pdl != NULL);
    PREFAST_DEBUGCHK(pdsDevice != NULL);
    DEBUGCHK(pdsDevice->pNext == NULL && pdsDevice->pPrev == NULL);
    DEBUGCHK(pdsDevice->dwRefCount == 1);
    DEBUGCHK(pdsDevice->pListHead == NULL);

    PMLOGMSG(ZONE_REFCNT | ZONE_DEVICE, 
        (_T("%s: adding 0x%08x ('%s') to list 0x%08x\r\n"),
        pszFname, pdsDevice, pdsDevice->pszName, pdl));

    // put the new device at the head of the list
    PMLOCK();
    pdsDevice->pListHead = pdl;
    pdsDevice->pNext = pdl->pList;
    pdsDevice->pPrev = NULL;
    if(pdl->pList != NULL) {
        pdl->pList->pPrev = pdsDevice;
    }
    pdl->pList = pdsDevice;

    // copy interface method pointers from the device class
    DEBUGCHK(pdl->pInterface != NULL);
    pdsDevice->pInterface = pdl->pInterface;

    DeviceStateAddRef(pdsDevice);
    PMUNLOCK();

    return fOk;
}

// this routine removes a device state structure from a list and decrements
// its reference count.
BOOL
DeviceStateRemList(PDEVICE_STATE pds)
{
    BOOL fOk = TRUE;
    SETFNAME(_T("DeviceStateRemList"));
    PREFAST_DEBUGCHK(pds != NULL);
    PREFAST_DEBUGCHK(pds->pListHead != NULL);
    
    PMLOGMSG(ZONE_REFCNT | ZONE_DEVICE, 
        (_T("%s: removing 0x%08x ('%s') from list 0x%08x\r\n"),
        pszFname, pds, pds->pszName, pds->pListHead));

    PMLOCK();

    // are we at the head of the list?
    if(pds->pPrev != NULL) {
        pds->pPrev->pNext = pds->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(pds->pNext != NULL) {
            pds->pNext->pPrev = NULL;
        }
        pds->pListHead->pList = pds->pNext;
    }
    
    // are we at the tail of the list?
    if(pds->pNext != NULL) {
        pds->pNext->pPrev = pds->pPrev;
    } else {
        if(pds->pPrev != NULL) {

⌨️ 快捷键说明

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