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

📄 mon.c

📁 此代码为WCE5.0下电源管理的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    HANDLE hEvents[3];
    LPTSTR pszFname = _T("PMMON!MonThreadProc");

    UNREFERENCED_PARAMETER(pvParam);

    ASSERT(ghPowerNotifications != NULL);
    ASSERT(ghDeviceNotifications != NULL);
    ASSERT(ghevTerminate != NULL);

    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);

    hEvents[0] = ghPowerNotifications;
    hEvents[1] = ghDeviceNotifications;
    hEvents[2] = ghevTerminate;

    while (1) 
    {
        DWORD dwStatus;

        // Block on our message queue.
        // This thread runs when the power manager writes a notification into the queue.
        dwStatus = WaitForMultipleObjects(3, hEvents, FALSE, INFINITE);
        if(dwStatus == WAIT_OBJECT_0) {
            ProcessPowerNotification(ghPowerNotifications);
        } else if(dwStatus == (WAIT_OBJECT_0 + 1)) {
            ProcessDeviceNotification(ghDeviceNotifications);
        } else if(dwStatus == (WAIT_OBJECT_0 + 2)) {
            RETAILMSG(1, (TEXT("%s: termination event signaled\r\n"), pszFname));
        } else {
            RETAILMSG(1, (TEXT("%s: WaitForMultipleObjects returned %d (error %d)\r\n"), pszFname,
                dwStatus, GetLastError()));
            break;
        }
    }

    return 0;
}

// this routine converts a string into a GUID and returns TRUE if the
// conversion was successful.
BOOL 
ConvertStringToGuid (LPCTSTR pszGuid, GUID *pGuid)
{
	UINT Data4[8];
	int  Count;
	BOOL fOk = FALSE;
	TCHAR *pszGuidFormat = _T("{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}");

	ASSERT(pGuid != NULL && pszGuid != NULL);
	__try
	{
		if (_stscanf(pszGuid, pszGuidFormat, &pGuid->Data1, 
		    &pGuid->Data2, &pGuid->Data3, &Data4[0], &Data4[1], &Data4[2], &Data4[3], 
		    &Data4[4], &Data4[5], &Data4[6], &Data4[7]) == 11)
		{
			for(Count = 0; Count < (sizeof(Data4) / sizeof(Data4[0])); Count++)
			{
	        	        pGuid->Data4[Count] = (UCHAR) Data4[Count];
			}
		}
		fOk = TRUE;
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
	}

	return fOk;
}

BOOL
RequestPMDeviceNotifications(DWORD cNotifications, HANDLE *phNotifications)
{
    BOOL fOk = TRUE;
    DWORD dwStatus;
    HKEY hk;
    TCHAR szBuf[MAX_PATH];
    LPTSTR pszFname = _T("PMMON!RequestPMDeviceNotifications");

    // enumerate all the device classes
    wsprintf(szBuf, _T("%s\\Interfaces"), PWRMGR_REG_KEY);
    dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szBuf, 0, 0, &hk);
    if(dwStatus == ERROR_SUCCESS) {
        DWORD dwIndex = 0;
        DWORD dwNotificationIndex = 0;
        do {
            DWORD cbValueName = MAX_PATH, dwType;
            GUID idInterface;

            dwStatus = RegEnumValue(hk, dwIndex, szBuf, &cbValueName, NULL,
                &dwType, NULL, NULL);
            if(dwStatus == ERROR_SUCCESS) {
                if(dwType != REG_SZ) {
                    RETAILMSG(TRUE, (_T("%s: invalid type for value '%s'\r\n"),
                        pszFname, szBuf));
                } else if(!ConvertStringToGuid(szBuf, &idInterface)) {
                    RETAILMSG(TRUE, (_T("%s: can't convert '%s' to GUID\r\n"),
                        pszFname, szBuf));
                } else if((phNotifications[dwNotificationIndex] = RequestDeviceNotifications(&idInterface, ghDeviceNotifications, TRUE)) == NULL) {
                    RETAILMSG(TRUE, (_T("%s: RequestDeviceNotifications('%s') failed\r\n"), 
                        pszFname, szBuf));
                } else {
                    dwNotificationIndex++;
                }

                // update the index
                dwIndex++;
            }
        } while(dwStatus == ERROR_SUCCESS && dwNotificationIndex < cNotifications);

        // check for abnormal termination of the loop
        if(dwStatus != ERROR_NO_MORE_ITEMS) {
            fOk = FALSE;
        }

        // close the registry handle
        RegCloseKey(hk);
    }

    return fOk;
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPWSTR lpCmdLine, int nCmShow)
{
    HANDLE hNotifications = NULL;
    HANDLE hDeviceNotifications[64];
    HANDLE ht;
    int i;
    LPTSTR pszFname = _T("PMMON:WinMain");
    
    MSGQUEUEOPTIONS msgOptions = {0};   

    UNREFERENCED_PARAMETER(hInst);
    UNREFERENCED_PARAMETER(hPrevInst);
    UNREFERENCED_PARAMETER(lpCmdLine);
    UNREFERENCED_PARAMETER(nCmShow);

    // clear globals
    memset(hDeviceNotifications, 0, sizeof(hDeviceNotifications));

    // create a termination event
    ghevTerminate = CreateEvent(NULL, FALSE, FALSE, _T("SOFTWARE/PMTestPrograms/PMMON/Terminate"));
    if(ghevTerminate == NULL) {
        RETAILMSG(TRUE, (_T("%s: CreateEvent() failed %d for termination event\r\n"),
            pszFname, GetLastError()));
        goto _Exit;
    }

    // did the event already exist?
    if(GetLastError() == ERROR_ALREADY_EXISTS) {
        // yes, kill the existing process
        RETAILMSG(TRUE, (_T("%s: Signaling termination event\r\n"), pszFname));
        SetEvent(ghevTerminate);
        goto _Exit;
    }
    
    // create a message queue for Power Manager notifications
    msgOptions.dwSize = sizeof(MSGQUEUEOPTIONS);
    msgOptions.dwFlags = 0;
    msgOptions.dwMaxMessages = QUEUE_ENTRIES;
    msgOptions.cbMaxMessage = sizeof(POWER_BROADCAST) + MAX_NAMELEN;
    msgOptions.bReadAccess = TRUE;

    ghPowerNotifications= CreateMsgQueue(NULL, &msgOptions);
    if (!ghPowerNotifications) {
        DWORD dwErr = GetLastError();
        RETAILMSG(1, (TEXT("%s:CreateMessageQueue ERROR:%d\n"), pszFname, dwErr));
        goto _Exit;
    }

    // request Power notifications
    hNotifications = RequestPowerNotifications(ghPowerNotifications, POWER_NOTIFY_ALL); // Flags
    if (!hNotifications) {
        DWORD dwErr = GetLastError();
        RETAILMSG(TRUE, (TEXT("%s:RequestPowerNotifications ERROR:%d\n"), pszFname, dwErr));
        goto _Exit;
    }

    // create message queues
    memset(&msgOptions, 0, sizeof(msgOptions));
    msgOptions.dwSize = sizeof(MSGQUEUEOPTIONS);
    msgOptions.dwFlags = 0;
    msgOptions.cbMaxMessage = PNP_QUEUE_SIZE;
    msgOptions.bReadAccess = TRUE;
    ghDeviceNotifications = CreateMsgQueue(NULL, &msgOptions);
    if(ghDeviceNotifications == NULL) {
        DWORD dwStatus = GetLastError();
        RETAILMSG(TRUE, (_T("%s:CreateMsgQueue() failed %d\r\n"), pszFname, dwStatus));
        goto _Exit;
    }

    // create the monitoring thread
    ht = CreateThread(NULL, 0, MonThreadProc, NULL, 0, NULL);
    if(ht) {
        // request device notifications (do this after the thread is
        // created so we don't drop any notifications)
        RequestPMDeviceNotifications(64, hDeviceNotifications);

        // wait for the thread to exit
        WaitForSingleObject(ht, INFINITE);
        CloseHandle(ht);
    }

_Exit:
    if(hNotifications) StopPowerNotifications(hNotifications);
    if(ghPowerNotifications) CloseMsgQueue(ghPowerNotifications);
    for(i = 0; i < 64 && hDeviceNotifications[i] != NULL; i++) {
        StopDeviceNotifications(hDeviceNotifications[i]);
    }
    if(ghDeviceNotifications) CloseMsgQueue(ghDeviceNotifications);
    if(ghevTerminate) CloseHandle(ghevTerminate);
    RETAILMSG(TRUE, (_T("%s: exiting\r\n"), pszFname));

    return 0;
}

// EOF

⌨️ 快捷键说明

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