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

📄 pmdevice.cpp

📁 此代码为WCE5.0下电源管理的源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                            }
                        }
                    }
                }
                
                // have we read all the configuration information we need from 
                // the new device
                if(!fOk) {
                    // no, delete the device
                    DeviceStateRemList(pds);
                } else {
                    // See if the device supports multiple handles.  Power manageable devices
                    // should allow multiple open handles, but if they don't we will have to open
                    // one before each access.
                    HANDLE hDevice = pds->pInterface->pfnOpenDevice(pds);
                    if(hDevice == INVALID_HANDLE_VALUE) {
                        PMLOGMSG(ZONE_WARN, (_T("%s: WARNING: '%s' does not support multiple handles\r\n"),
                            pszFname));
                        pds->pInterface->pfnCloseDevice(pds->hDevice);
                        pds->hDevice = INVALID_HANDLE_VALUE;
                    } else {
                        // close the second handle, since we don't need it
                        pds->pInterface->pfnCloseDevice(hDevice);
                    }
                    
                    // initialize the new device's power state variables
                    UpdateDeviceState(pds);
                }
            }
        }
        
        // we are done with the device pointer
        if(pds != NULL) {
            DeviceStateDecRef(pds);
        }
    } else {
        PMLOGMSG(ZONE_WARN, (_T("%s: class for device '%s' not supported\r\n"),
            pszFname, pszName));
    }
}

// this routine removes a device from the list of managed devices.  When
// the device's reference count goes to zero it will be deallocated.
VOID
RemoveDevice(LPCGUID guidDevClass, LPCTSTR pszName)
{
    SETFNAME(_T("RemoveDevice"));

    PMLOGMSG(ZONE_DEVICE, (_T("%s: removing '%s' from %08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x\r\n"), 
        pszFname, pszName, 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]));

    // figure out onto which list this device should be added
    PDEVICE_LIST pdl = GetDeviceListFromClass(guidDevClass);

    // did we find the list?
    if(pdl != NULL) {
        // check for duplicates
        PDEVICE_STATE pds = DeviceStateFindList(pdl, pszName);
        if(pds == NULL) {
            PMLOGMSG(ZONE_WARN, (_T("%s: '%s' not in class list\r\n"),
                pszFname, pszName));
        } else {
            // disconnect the device from the list
            DeviceStateRemList(pds);
            
            // if we are a child device, decrement the parent pointer's
            // reference count
            if(pds->pParent != NULL) {
                DeviceStateDecRef(pds->pParent);
                pds->pParent = NULL;
            }
            
            // if we are a parent device, remove child devices (if any)
            if((pds->caps.Flags & POWER_CAP_PARENT) != 0) {
                // look for a match across all lists, since the child may not
                // be of the same class
                for(pdl = gpDeviceLists; pdl != NULL; pdl = pdl->pNext) {
                    PDEVICE_STATE pCur, pNext;
                    pCur = pdl->pList;
                    while(pCur != NULL) {
                        pNext = pCur->pNext;
                        if(pCur->pParent == pds) {
                            RemoveDevice(pdl->pGuid, pCur->pszName);
                        }
                        pCur = pNext;
                    }
                }
            }
            
            // we're done with the device pointer
            DeviceStateDecRef(pds);
        }
    }
}

// This routine looks up a given device and passes back its current power state
// via the pCurDx pointer.  It returns the following error codes:
//      ERROR_SUCCESS - device found, *pCurDx updated successfully
//      ERROR_FILE_NOT_FOUND - device not found
//      ERROR_INVALID_PARAMETER - bad device ID, flags, or pCurDx pointer.
EXTERN_C DWORD WINAPI
PmGetDevicePower(PVOID pvDevice, DWORD dwDeviceFlags, PCEDEVICE_POWER_STATE pCurDx)
{
    DWORD dwStatus = ERROR_FILE_NOT_FOUND;
    PDEVICEID pdi = NULL;
    SETFNAME(_T("PmGetDevicePower"));

    PMLOGMSG(ZONE_API || ZONE_DEVICE, (_T("+%s: device %s, flags 0x%08x\r\n"),
        pszFname, (dwDeviceFlags & POWER_NAME) != 0 ? (LPTSTR) pvDevice : _T("<UNKNOWN>"),
        dwDeviceFlags));

    // sanity check parameters
    if(pvDevice == NULL 
    || pCurDx == NULL
    || (pdi = DeviceIdParseNameString((LPCTSTR) pvDevice, dwDeviceFlags)) == NULL) {
        dwStatus = ERROR_INVALID_PARAMETER;
    } else {
        PDEVICE_LIST pdl;
        
        // look for the device list and the device
        pdl = GetDeviceListFromClass(pdi->pGuid);
        if(pdl != NULL) {
            PDEVICE_STATE pds = DeviceStateFindList(pdl, pdi->pszName);
            if(pds != NULL) {
                CEDEVICE_POWER_STATE curDx = PwrDeviceUnspecified;

                // how are we supposed to obtain the data?
                if((dwDeviceFlags & POWER_FORCE) == 0) {
                    // use our cached value
                    PMLOCK();
                    curDx = pds->curDx;
                    PMUNLOCK();
                    dwStatus = ERROR_SUCCESS;
                } else {
                    // request the device's power status
                    dwStatus = GetDevicePower(pds, &curDx);
                }

                // do we have a value to pass back?
                if(dwStatus == ERROR_SUCCESS) {
                    __try {
                        // yes, update the caller's parameter
                        *pCurDx = curDx;
                    }
                    __except(EXCEPTION_EXECUTE_HANDLER) {
                        PMLOGMSG(ZONE_WARN, (_T("%s: exception updating pCurDx 0x%08x\r\n"),
                            pszFname, pCurDx));
                        dwStatus = ERROR_INVALID_PARAMETER;
                    }
                }
                
                // done with its pointer
                DeviceStateDecRef(pds);
            }
        }
    }

    // release resources
    if(pdi != NULL) DeviceIdDestroy(pdi);

    PMLOGMSG(ZONE_API || ZONE_DEVICE || (dwStatus != ERROR_SUCCESS && ZONE_WARN), 
        (_T("-%s: returning dwStatus %d\r\n"), pszFname, dwStatus));

    // return our status
    return dwStatus;
}

// This routine looks up a given device and sets its device power state to the
// value in dwState.  It returns the following values:
//      ERROR_SUCCESS - device found and power state updated
//      ERROR_FILE_NOT_FOUND - device not found
//      ERROR_WRITE_FAULT - attempt to update the device power failed
//      ERROR_INVALID_PARAMETER - bad device ID, flags, or dwState value.

EXTERN_C DWORD WINAPI 
PmSetDevicePower(PVOID pvDevice, DWORD dwDeviceFlags, CEDEVICE_POWER_STATE newDx)
{
    DWORD dwStatus = ERROR_FILE_NOT_FOUND;
    PDEVICEID pdi = NULL;
    SETFNAME(_T("PmSetDevicePower"));

    PMLOGMSG(ZONE_API || ZONE_DEVICE, (_T("+%s: device %s, flags 0x%08x, new Dx %d\r\n"),
        pszFname, (dwDeviceFlags & POWER_NAME) != 0 ? (LPTSTR) pvDevice : _T("<UNKNOWN>"),
        dwDeviceFlags, newDx));

    PMENTERUPDATE();

    // sanity check parameters
    if(pvDevice == NULL 
    || ((newDx < D0 || newDx > D4) && newDx != PwrDeviceUnspecified)
    || (pdi = DeviceIdParseNameString((LPCTSTR) pvDevice, dwDeviceFlags)) == NULL) {
        dwStatus = ERROR_INVALID_PARAMETER;
    } else {
        PDEVICE_LIST pdl;
        BOOL fOk = TRUE;

        // look for the device list and the device
        pdl = GetDeviceListFromClass(pdi->pGuid);
        if(pdl != NULL) {
            PDEVICE_STATE pds = DeviceStateFindList(pdl, pdi->pszName);
            if(pds != NULL) {
                // are we imposing a set value or are we removing a set value?
                if(newDx == PwrDeviceUnspecified) {
                    // remove the set value
                    PMLOCK();
                    pds->setDx = PwrDeviceUnspecified;
                    PMUNLOCK();
                    
                    // let the device find its own power level
                    UpdateDeviceState(pds);
                    
                    // we've removed the set constraint, no matter what UpdateDeviceStatus() did
                    dwStatus = ERROR_SUCCESS;
                } else {
                    // found the device, now try to update it
                    PMLOCK();
                    pds->setDx = newDx;
                    PMUNLOCK();
                    fOk = UpdateDeviceState(pds);
                    if(!fOk) {
                        PMLOCK();
                        pds->setDx = PwrDeviceUnspecified;
                        PMUNLOCK();
                        dwStatus = ERROR_WRITE_FAULT;
                    } else {
                        dwStatus = ERROR_SUCCESS;
                    }
                }
                
                // done with the device pointer
                DeviceStateDecRef(pds);
            }
        }
    }

    PMLEAVEUPDATE();

    // release resources
    if(pdi != NULL) DeviceIdDestroy(pdi);

    PMLOGMSG(ZONE_API || ZONE_DEVICE || (dwStatus != ERROR_SUCCESS && ZONE_WARN), 
        (_T("-%s: returning dwStatus %d\r\n"), pszFname, dwStatus));

    // return our status
    return dwStatus;
}

// This routine is invoked when a device driver wants to have the power manager
// adjust its power state.  Power manager will attempt to honor the request
// within the constraints imposed on it by the current system power state,
// application requirements, and user set operations.
EXTERN_C DWORD WINAPI 
PmDevicePowerNotify(PVOID pvDevice, CEDEVICE_POWER_STATE reqDx, 
                    DWORD dwDeviceFlags)
{
    DWORD dwStatus = ERROR_SUCCESS;
    PDEVICEID pdi = NULL;
    SETFNAME(_T("PmDevicePowerNotify"));

    PMLOGMSG(ZONE_API, (_T("+%s: device '%s' req %d, flags 0x%08x\r\n"), pszFname, 
        (dwDeviceFlags & POWER_NAME) != 0 ? (LPTSTR) pvDevice : _T("<UNKNOWN>"),
        reqDx, dwDeviceFlags));

    // sanity check parameters
    if(pvDevice == NULL 
    || (reqDx < D0 || reqDx > D4)
    || (pdi = DeviceIdParseNameString((LPCTSTR) pvDevice, dwDeviceFlags)) == NULL) {
        dwStatus = ERROR_INVALID_PARAMETER;
    } else {
        PDEVICE_LIST pdl;
        BOOL fOk = TRUE;

        // look for the device list and the device
        pdl = GetDeviceListFromClass(pdi->pGuid);
        if(pdl == NULL) {
            dwStatus = ERROR_FILE_NOT_FOUND;
        } else {
            PDEVICE_STATE pds = DeviceStateFindList(pdl, pdi->pszName);
            if(pds == NULL) {
                dwStatus = ERROR_FILE_NOT_FOUND;
            } else {
                PMLOCK();
                
                PMLOGMSG(ZONE_DEVICE, 
                    (_T("%s: device '%s' request for D%d, curDx D%d, floorDx D%d, ceilingDx D%d, setDx %d\r\n"),
                    pszFname, pds->pszName, reqDx, pds->curDx, pds->floorDx, pds->ceilingDx, pds->setDx));
                
                // record this state change request
                pds->lastReqDx = reqDx;

                PMUNLOCK();

                // change the device power state if necessary
                fOk = UpdateDeviceState(pds);
                if(!fOk) {
                    PMLOGMSG(ZONE_WARN, 
                        (_T("%s: SetDevicePower('%s') failed when requesting D%d\r\n"),
                        pszFname, pds->pszName, reqDx));
                    dwStatus = ERROR_WRITE_FAULT;
                }
                
                // done with the device state pointer
                DeviceStateDecRef(pds);
            }
        }
    }

    // release resources
    if(pdi != NULL) DeviceIdDestroy(pdi);

    PMLOGMSG((dwStatus != ERROR_SUCCESS && ZONE_WARN) || ZONE_API,
        (_T("%s: returning %d\r\n"), pszFname, dwStatus));
    return dwStatus;
}

⌨️ 快捷键说明

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