📄 pmutils.cpp
字号:
ppn->pPrev->pNext = NULL;
}
}
// clear list pointers
ppn->pNext = NULL;
ppn->pPrev = NULL;
// delete the structure and its members
PowerNotificationDestroy(ppn);
PMUNLOCK();
return fOk;
}
// ------------------------ DEVICE LISTS ---------------------
// This routine creates a device list entry and returns a pointer to it, or NULL
// if there's an error.
PDEVICE_LIST
DeviceListCreate(LPCGUID pClass)
{
PDEVICE_LIST pdl = NULL;
HANDLE hMsgQ = NULL;
MSGQUEUEOPTIONS msgOptions;
SETFNAME(_T("DeviceListCreate"));
PMLOGMSG(ZONE_INIT || ZONE_DEVICE,
(_T("%s: creating list entry for class %08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x\r\n"),
pszFname, pClass->Data1, pClass->Data2, pClass->Data3,
(pClass->Data4[0] << 8) + pClass->Data4[1], pClass->Data4[2], pClass->Data4[3],
pClass->Data4[4], pClass->Data4[5], pClass->Data4[6], pClass->Data4[7]));
// allocate structure members
pdl = (PDEVICE_LIST) PmAlloc(sizeof(*pdl) + sizeof(GUID));
// create message queues
memset(&msgOptions, 0, sizeof(msgOptions));
msgOptions.dwSize = sizeof(MSGQUEUEOPTIONS);
msgOptions.dwFlags = 0;
msgOptions.cbMaxMessage = PNP_QUEUE_SIZE;
msgOptions.bReadAccess = TRUE;
hMsgQ = CreateMsgQueue(NULL, &msgOptions);
if(hMsgQ == NULL) {
DWORD dwStatus = GetLastError();
PMLOGMSG(ZONE_ERROR, (_T("%s: CreateMsgQueue() failed %d\r\n"), pszFname, dwStatus));
}
// initialize the structure
if(pdl != NULL && hMsgQ != NULL) {
LPGUID pGuid = (LPGUID) ((LPBYTE) pdl + sizeof(*pdl));
memset(pdl, 0, sizeof(pdl));
*pGuid = *pClass;
pdl->pGuid = pGuid;
pdl->hMsgQ = hMsgQ;
pdl->hnClass = NULL;
pdl->pInterface = NULL;
pdl->pList = NULL;
pdl->pNext = NULL;
} else {
// some kind of error, release resources
if(pdl != NULL) PmFree(pdl);
if(hMsgQ != NULL) CloseMsgQueue(hMsgQ);
pdl = NULL;
}
PMLOGMSG(pdl == NULL && ZONE_WARN, (_T("%s: returning 0x%08x\r\n"), pszFname, pdl));
return pdl;
}
// This routine frees a device list entry. The list must be empty
// when this routine is called, and it must not point to another
// list (ie, pNext must be null).
VOID
DeviceListDestroy(PDEVICE_LIST pdl)
{
SETFNAME(_T("DeviceListDestroy"));
PMLOGMSG(ZONE_INIT || ZONE_DEVICE,
(_T("%s: deleting list entry for class %08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x\r\n"),
pszFname, pdl->pGuid->Data1, pdl->pGuid->Data2, pdl->pGuid->Data3,
(pdl->pGuid->Data4[0] << 8) + pdl->pGuid->Data4[1], pdl->pGuid->Data4[2], pdl->pGuid->Data4[3],
pdl->pGuid->Data4[4], pdl->pGuid->Data4[5], pdl->pGuid->Data4[6], pdl->pGuid->Data4[7]));
DEBUGCHK(pdl->pNext == NULL);
DEBUGCHK(pdl->pList == NULL);
DEBUGCHK(pdl->hnClass == NULL);
if(pdl->hMsgQ) CloseMsgQueue(pdl->hMsgQ);
PmFree(pdl);
}
// this routine determines to which device list a particular device class
// corresponds
PDEVICE_LIST
GetDeviceListFromClass(LPCGUID guidDevClass)
{
PDEVICE_LIST pdl;
SETFNAME(_T("GetDeviceListFromClass"));
PREFAST_DEBUGCHK(guidDevClass != NULL);
// look for a match
__try {
for(pdl = gpDeviceLists; pdl != NULL; pdl = pdl->pNext) {
if(*pdl->pGuid == *guidDevClass) {
break;
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER) {
PMLOGMSG(TRUE, (_T("%s: exception accessing guidDevClass 0x%08x\r\n"),
pszFname, guidDevClass));
pdl = NULL;
}
return pdl;
}
// ------------------------ SYSTEM POWER STATES ---------------------
// this routine allocates a structure describing a system power state.
PSYSTEM_POWER_STATE
SystemPowerStateCreate(LPCTSTR pszName)
{
PSYSTEM_POWER_STATE psps;
SETFNAME(_T("SystemPowerStateCreate"));
PREFAST_DEBUGCHK(pszName != NULL);
DWORD cchName;
__try {
cchName = _tcslen(pszName);
DWORD dwSize = sizeof(*psps) + ((cchName + 1) * sizeof(pszName[0]));
psps = (PSYSTEM_POWER_STATE) PmAlloc(dwSize);
}
__except(EXCEPTION_EXECUTE_HANDLER) {
PMLOGMSG(ZONE_WARN, (_T("%s: exception calculating size\r\n"), pszFname));
psps = NULL;
}
if(psps != NULL) {
memset(psps, 0, sizeof(*psps));
__try {
LPTSTR pszNameCopy = (LPTSTR) ((LPBYTE) psps + sizeof(*psps));
// Copy the name, converting to lower case. We want to avoid doing
// case-sensitive comparisons in the platform code while file system
// access may be disabled.
for (DWORD dwIndex = 0; dwIndex < cchName; dwIndex++) {
pszNameCopy[dwIndex] = _totlower(pszName[dwIndex]);
}
pszNameCopy[cchName] = 0;
psps->pszName = pszNameCopy;
}
__except(EXCEPTION_EXECUTE_HANDLER) {
PMLOGMSG(ZONE_WARN, (_T("%s: exception copying name\r\n"),
pszFname));
PmFree(psps);
psps = NULL;
}
}
PMLOGMSG(psps == NULL && ZONE_WARN,
(_T("%s: couldn't allocate structure\r\n"), pszFname));
return psps;
}
// this routine deallocates a system power state structure
BOOL
SystemPowerStateDestroy(PSYSTEM_POWER_STATE psps)
{
BOOL fOk = TRUE;
if(psps != NULL) {
PmFree(psps);
}
return fOk;
}
// ------------------------ ACTIVITY TIMER LISTS ---------------------
// This routine allocates and initializes an activity timer structure.
// The structure has a name and several events, one of which is a public
// (ie named) event whose name is derived from the activity timer name.
// It also contains an array of wake sources that are associated with
// the activity timer. This is constructed from a REG_MULTI_SZ value,
// each component string of which is a wake source number represented in
// decimal. The wake source values must be compatible with
// IOCTL_HAL_GET_WAKE_SOURCE.
PACTIVITY_TIMER
ActivityTimerCreate(LPTSTR pszName, DWORD dwTimeout, LPTSTR pszSources)
{
PACTIVITY_TIMER pat = NULL;
DWORD dwWakeSources, dwSize;
LPTSTR pszSource;
TCHAR szPath[MAX_PATH];
BOOL fOk = TRUE;
SETFNAME(_T("ActivityTimerCreate"));
PREFAST_DEBUGCHK(pszName != NULL );
PREFAST_DEBUGCHK(pszSources != NULL);
DEBUGCHK(*pszName != 0);
// calculate the number of wake sources and allocate an array for them
dwWakeSources = 0;
pszSource = pszSources;
while(*pszSource != 0) {
pszSource += _tcslen(pszSource) + 1;
dwWakeSources++;
}
// allocate and initialize structure and members
dwSize = sizeof(*pat) + ((dwWakeSources + 1) * sizeof(pat->pdwWakeSources[0]))
+ ((_tcslen(pszName) + 1) * sizeof(*pszName));
pat = (PACTIVITY_TIMER) PmAlloc(dwSize);
if(pat != NULL) {
memset(pat, 0, sizeof(*pat));
pat->dwTimeout = dwTimeout; // timeout in milliseconds
if(pat->dwTimeout == 0) {
pat->dwTimeLeft = INFINITE;
} else {
pat->dwTimeLeft = pat->dwTimeout;
}
pat->pdwWakeSources = (LPDWORD) ((LPBYTE) pat + sizeof(*pat));
pat->pszName = (LPTSTR) ((LPBYTE) pat->pdwWakeSources
+ ((dwWakeSources + 1) * sizeof(pat->pdwWakeSources[0])));
// create the reset event
if(fOk &&
_sntprintf(szPath, dim(szPath), _T("PowerManager/ActivityTimer/%s"), pszName) == (-1)) {
PMLOGMSG(ZONE_WARN, (_T("%s: couldn't format event name for activity timer '%s'\r\n"),
pszFname, pszName));
fOk = FALSE;
} else {
szPath[dim(szPath)-1] = 0;
pat->hevReset = CreateEvent(NULL, FALSE, FALSE, szPath);
}
// create the event indicating activity
if(fOk &&
_sntprintf(szPath, dim(szPath), _T("PowerManager/%s_Active"), pszName) == (-1)) {
PMLOGMSG(ZONE_WARN, (_T("%s: couldn't format event name for activity timer '%s'\r\n"),
pszFname, pszName));
fOk = FALSE;
} else {
szPath[dim(szPath)-1] = 0;
pat->hevActive = CreateEvent(NULL, TRUE, FALSE, szPath);
}
// create the event indicating inactivity
if(fOk &&
_sntprintf(szPath, dim(szPath), _T("PowerManager/%s_Inactive"), pszName) == (-1)) {
PMLOGMSG(ZONE_WARN, (_T("%s: couldn't format event name for activity timer '%s'\r\n"),
pszFname, pszName));
fOk = FALSE;
} else {
szPath[dim(szPath)-1] = 0;
pat->hevInactive = CreateEvent(NULL, TRUE, FALSE, szPath);
}
// did we get everything we needed?
if(pat->hevReset == NULL || pat->hevActive == NULL || pat->hevInactive == NULL) {
PMLOGMSG(ZONE_WARN, (_T("%s: resource allocation failed for '%s'\r\n"),
pszFname, pszName));
fOk = FALSE;
} else {
DWORD dwIndex;
// init activity name
_tcscpy(pat->pszName, pszName);
// init wake sources
dwIndex = 0;
pszSource = pszSources;
while(fOk && *pszSource != 0 && dwIndex < dwWakeSources) {
LPTSTR pszEnd;
pat->pdwWakeSources[dwIndex] = _tcstol(pszSource, &pszEnd, 0);
if(*pszEnd != 0) {
PMLOGMSG(ZONE_WARN,
(_T("%s: can't parse wake source '%s' for timer '%s'\r\n"),
pszFname, pszSource, pszName));
fOk = FALSE;
}
pszSource += _tcslen(pszSource) + 1;
dwIndex++;
}
// terminate the list with SYSINTR_NOP
pat->pdwWakeSources[dwIndex] = SYSINTR_NOP;
}
}
// clean up if necessary
if(!fOk && pat != NULL) {
if(pat->hevReset != NULL) CloseHandle(pat->hevReset);
if(pat->hevActive != NULL) CloseHandle(pat->hevActive);
if(pat->hevInactive != NULL) CloseHandle(pat->hevInactive);
PmFree(pat);
pat = NULL;
}
PMLOGMSG(ZONE_INIT || (pat == NULL && ZONE_WARN),
(_T("%s: ActivityTimerCreate('%s') returning 0x%08x\r\n"), pszFname, pszName));
return pat;
}
// This routine deallocates an activity timer structure and frees any resources
// associated with it.
BOOL
ActivityTimerDestroy(PACTIVITY_TIMER pat)
{
BOOL fOk = TRUE;
// free the structure and its members
if(pat != NULL) {
if(pat->hevReset != NULL) CloseHandle(pat->hevReset);
if(pat->hevActive != NULL) CloseHandle(pat->hevActive);
if(pat->hevInactive != NULL) CloseHandle(pat->hevInactive);
PmFree(pat);
}
return fOk;
}
// This routine looks up an activity timer by name and returns a pointer to
// its corresponding structure. If it can't find the timer, it returns NULL.
PACTIVITY_TIMER
ActivityTimerFindByName(LPCTSTR pszName)
{
PACTIVITY_TIMER pat = NULL;
SETFNAME(_T("ActivityTimerFindByName"));
PMLOCK();
if(gppActivityTimers != NULL) {
DWORD dwTimerIndex = 0;
while((pat = gppActivityTimers[dwTimerIndex]) != NULL) {
if(_tcscmp(pat->pszName, pszName) == 0) {
break;
}
dwTimerIndex++;
}
}
PMUNLOCK();
PMLOGMSG(ZONE_TIMERS, (_T("%s: search for '%s' returning 0x%08x\r\n"), pszFname,
pszName, pat));
return pat;
}
// This routine looks up the activity timer associcated with a wake source
// and returns a pointer to its corresponding structure. If it can't
// find the timer, it returns NULL.
PACTIVITY_TIMER
ActivityTimerFindByWakeSource(DWORD dwWakeSource)
{
PACTIVITY_TIMER pat = NULL;
BOOL fDone = FALSE;
SETFNAME(_T("ActivityTimerFindByWakeSource"));
PMLOCK();
if(gppActivityTimers != NULL) {
DWORD dwTimerIndex = 0;
while(!fDone && (pat = gppActivityTimers[dwTimerIndex]) != NULL) {
DWORD dwSourceIndex = 0;
while(pat->pdwWakeSources[dwSourceIndex] != 0) {
if(pat->pdwWakeSources[dwSourceIndex] == dwWakeSource) {
fDone = TRUE;
break;
}
dwSourceIndex++;
}
dwTimerIndex++;
}
}
PMUNLOCK();
PMLOGMSG(ZONE_TIMERS, (_T("%s: search for %d (0x%x) returning 0x%08x\r\n"), pszFname,
dwWakeSource, dwWakeSource, pat));
return pat;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -