📄 pmutils.cpp
字号:
pds->pPrev->pNext = NULL;
}
}
// clear list pointers
pds->pNext = NULL;
pds->pPrev = NULL;
pds->pListHead = NULL;
// decrement the reference count
DeviceStateDecRef(pds);
PMUNLOCK();
return fOk;
}
// This routine looks for a device on a list. If it finds the device, it
// increments its reference counter and returns a pointer to it. The caller
// should decrement the reference counter when it is done with the pointer.
// Note that the search is case sensitive.
PDEVICE_STATE
DeviceStateFindList(PDEVICE_LIST pdl, LPCTSTR pszName)
{
PDEVICE_STATE pds;
SETFNAME(_T("DeviceStateFindList"));
PMLOCK();
__try {
// look for a match
for(pds = pdl->pList; pds != NULL; pds = pds->pNext) {
if(_tcscmp(pds->pszName, pszName) == 0) {
// increment the reference count and exit
DeviceStateAddRef(pds);
break;
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER) {
PMLOGMSG(ZONE_WARN, (_T("%s: exception searching list\r\n"), pszFname));
pds = NULL;
}
PMUNLOCK();
return pds;
}
// ------------------------ DEVICE POWER RESTRICTION MANAGEMENT ----------
// this routine creates a data structure describing a device. Its initial
// reference count is one.
PDEVICE_POWER_RESTRICTION
PowerRestrictionCreate(PDEVICEID pDeviceId, HANDLE hOwner, CEDEVICE_POWER_STATE Dx,
LPCTSTR pszSystemState, DWORD dwFlags)
{
PDEVICE_POWER_RESTRICTION pdpr = NULL;
BOOL fOk = TRUE;
SETFNAME(_T("PowerRestrictionCreate"));
__try {
LPTSTR pszSystemStateCopy;
PDEVICEID pDeviceIdCopy = NULL;
DWORD dwDeviceIdSize = DeviceIdSize(pDeviceId);
DWORD cchSystemState;
// allocate resources
DWORD dwSize = sizeof(*pdpr) + dwDeviceIdSize;
if(pszSystemState != NULL) {
cchSystemState = _tcslen(pszSystemState);
dwSize += ((cchSystemState + 1) * sizeof(pszSystemState[0]));
}
pdpr = (PDEVICE_POWER_RESTRICTION) PmAlloc(dwSize);
if(pdpr == NULL) {
fOk = FALSE;
}
if(fOk) {
// copy the device ID
if(pDeviceId != NULL) {
pDeviceIdCopy = (PDEVICEID) ((LPBYTE) pdpr + sizeof(*pdpr));
pDeviceIdCopy = DeviceIdCloneIntoBuffer(pDeviceId, pDeviceIdCopy, dwDeviceIdSize);
if(pDeviceIdCopy == NULL) {
fOk = FALSE;
}
}
}
if(fOk) {
// copy the system power state name, if it's present
if(pszSystemState != NULL) {
// get a pointer to the aggregated buffer we just allocated
pszSystemStateCopy = (LPTSTR) ((LPBYTE) pdpr + sizeof(*pdpr) + dwDeviceIdSize);
// Do the copy here because once it's assigned to the structure
// our allocated buffer will be treated as const. Convert to lowercase
// so that we avoid doing localized comparisons when accessing the requirement
// data.
for (DWORD dwIndex = 0; dwIndex < cchSystemState; dwIndex++) {
pszSystemStateCopy[dwIndex] = _totlower(pszSystemState[dwIndex]);
}
pszSystemStateCopy[cchSystemState] = 0;
} else {
pszSystemStateCopy = NULL;
}
}
// initialize the structure
if(fOk) {
memset(pdpr, 0, sizeof(*pdpr));
pdpr->pDeviceId = pDeviceIdCopy;
pdpr->hOwner = hOwner;
pdpr->devDx = Dx;
pdpr->pszSystemState = pszSystemStateCopy;
pdpr->dwFlags = dwFlags;
pdpr->pNext = NULL;
pdpr->pPrev = NULL;
}
}
__except(EXCEPTION_EXECUTE_HANDLER) {
PMLOGMSG(ZONE_WARN, (_T("%s: exception during structure initialization\r\n"),
pszFname));
fOk = FALSE;
}
// clean up if necessary
if(!fOk) {
if(pdpr != NULL) {
PmFree(pdpr);
pdpr = NULL;
}
}
PMLOGMSG(pdpr == NULL && ZONE_WARN, (_T("%s: couldn't create structure for '%s'\r\n"),
pszFname, pDeviceId->pszName != NULL ? pDeviceId->pszName : _T("<NULL>")));
return pdpr;
}
// this routine deallocates a device state structure. It returns TRUE if
// successful, FALSE otherwise.
BOOL
PowerRestrictionDestroy(PDEVICE_POWER_RESTRICTION pdpr)
{
BOOL fOk = TRUE;
if(pdpr != NULL) {
PmFree(pdpr);
}
return fOk;
}
// this routine adds a device state structure to a list and increments its
// reference count. It returns TRUE if successful, FALSE otherwise.
BOOL
PowerRestrictionAddList(PPDEVICE_POWER_RESTRICTION ppListHead, PDEVICE_POWER_RESTRICTION pdpr)
{
BOOL fOk = TRUE;
PREFAST_DEBUGCHK(ppListHead != NULL);
PREFAST_DEBUGCHK(pdpr != NULL);
DEBUGCHK(pdpr->pNext == NULL && pdpr->pPrev == NULL);
DEBUGCHK(ppListHead != NULL);
// put the new device at the head of the list
PMLOCK();
pdpr->pNext = *ppListHead;
pdpr->pPrev = NULL;
if(*ppListHead != NULL) {
(*ppListHead)->pPrev = pdpr;
}
*ppListHead = pdpr;
PMUNLOCK();
return fOk;
}
// this routine removes a device state structure from a list and decrements
// its reference count.
BOOL
PowerRestrictionRemList(PPDEVICE_POWER_RESTRICTION ppListHead, PDEVICE_POWER_RESTRICTION pdpr)
{
BOOL fOk = TRUE;
PREFAST_DEBUGCHK(ppListHead != NULL);
PMLOCK();
// are we at the head of the list?
if(pdpr->pPrev != NULL) {
pdpr->pPrev->pNext = pdpr->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(pdpr->pNext != NULL) {
pdpr->pNext->pPrev = NULL;
}
*ppListHead = pdpr->pNext;
}
// are we at the tail of the list?
if(pdpr->pNext != NULL) {
pdpr->pNext->pPrev = pdpr->pPrev;
} else {
if(pdpr->pPrev != NULL) {
pdpr->pPrev->pNext = NULL;
}
}
// clear list pointers
pdpr->pNext = NULL;
pdpr->pPrev = NULL;
// delete the entry
PMUNLOCK();
return fOk;
}
// This routine looks for a power restriction on a list. If it finds the entry, it
// increments its reference counter and returns a pointer to it. The caller
// should decrement the reference counter when it is done with the pointer. The system
// power state name is expected to be lower-case, to avoid doing localized string comparisons.
PDEVICE_POWER_RESTRICTION
PowerRestrictionFindList(PDEVICE_POWER_RESTRICTION pList,
PDEVICEID pDeviceId, LPCTSTR pszSystemState)
{
PDEVICE_POWER_RESTRICTION pdpr;
SETFNAME(_T("PowerRestrictionFindList"));
PMLOCK();
__try {
// look for a match
for(pdpr = pList; pdpr != NULL; pdpr = pdpr->pNext) {
if(DeviceIdsAreEqual(pdpr->pDeviceId, pDeviceId)
&& (pszSystemState == NULL && pdpr->pszSystemState == NULL
|| (pszSystemState != NULL && pdpr->pszSystemState != NULL
&& _tcscmp(pszSystemState, pdpr->pszSystemState) == 0))) {
break;
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER) {
PMLOGMSG(ZONE_WARN, (_T("%s: exception while searching list\r\n"),
pszFname));
pdpr = NULL;
}
PMUNLOCK();
return pdpr;
}
// This routine checks that a particular power restriction exists on a list.
// It returns TRUE if it does, FALSE if it can't be matched. The comparison
// is based on pointer value, not on the contents of the pointer.
BOOL
PowerRestrictionCheckList(PDEVICE_POWER_RESTRICTION pList,
PDEVICE_POWER_RESTRICTION pdpr)
{
PDEVICE_POWER_RESTRICTION pdprTraveller;
BOOL fFound = FALSE;
PMLOCK();
// look for a match
for(pdprTraveller = pList; pdprTraveller != NULL; pdprTraveller = pdprTraveller->pNext) {
if(pdprTraveller == pdpr) {
fFound = TRUE;
break;
}
}
PMUNLOCK();
return fFound;
}
// ------------------------ 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) {
PMLOGMSG(ZONE_WARN,
(_T("%s: OpenMsgQueue() failed %d (owner 0x%08x, source q 0x%08x)\r\n"),
pszFname, GetLastError(), hOwner, hMsgQ));
PmFree(ppn);
ppn = NULL;
}
}
PMLOGMSG(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) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -