BOOL CreateAPnpMsgQueue(PHANDLE phQueue, PHANDLE phNoti, GUID inGUID ) { if(phQueue == NULL || phNoti == NULL){ return FALSE; } MSGQUEUEOPTIONS msgqopts = {0}; msgqopts.dwSize = sizeof(MSGQUEUEOPTIONS); msgqopts.dwFlags = 0; msgqopts.cbMaxMessage = QUEUE_ITEM_SIZE; msgqopts.bReadAccess = TRUE; *phQueue = NULL; *phQueue = CreateMsgQueue(NULL, &msgqopts); if(*phQueue == NULL){ return FALSE; } *phNoti = RequestDeviceNotifications(&inGUID, *phQueue, FALSE); if(*phNoti == NULL){ CloseMsgQueue(hPnpQueue); return FALSE; } return TRUE; }
static void createDeviceNotificationQueue(HANDLE& queue, HANDLE& notif) { MSGQUEUEOPTIONS msgopts; msgopts.dwSize = sizeof(msgopts); msgopts.dwFlags = 0; msgopts.dwMaxMessages = 0; msgopts.cbMaxMessage = sizeof(DEVDETAIL) + MAX_DEVCLASS_NAMELEN; msgopts.bReadAccess = TRUE; queue = CreateMsgQueue(NULL, &msgopts); notif = RequestDeviceNotifications(UkwDriverGUID(), queue, TRUE); }
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) { RetailPrint (_T("%s: invalid type for value '%s'\r\n"), pszFname, szBuf); } else if(!ConvertStringToGuid(szBuf, &idInterface)) { RetailPrint (_T("%s: can't convert '%s' to GUID\r\n"), pszFname, szBuf); } else if((phNotifications[dwNotificationIndex] = RequestDeviceNotifications(&idInterface, ghDeviceNotifications, TRUE)) == NULL) { RetailPrint (_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; }
DWORD WINAPI PnpThreadProc(LPVOID lpvParam) { DWORD dwStatus; HANDLE hnGeneric = NULL; HANDLE hevReady = (HANDLE) lpvParam; HANDLE hEvents[MAXIMUM_WAIT_OBJECTS]; DWORD dwNumEvents = 0; BOOL fDone = FALSE; BOOL fOk; INT iPriority; PDEVICE_LIST pdl; SETFNAME(_T("PnpThreadProc")); PMLOGMSG(ZONE_INIT, (_T("+%s: thread 0x%08x\r\n"), pszFname, GetCurrentThreadId())); // set the thread priority if(!GetPMThreadPriority(_T("PnPPriority256"), &iPriority)) { iPriority = DEF_PNP_THREAD_PRIORITY; } CeSetThreadPriority(GetCurrentThread(), iPriority); // first list entry is the exit event hEvents[dwNumEvents++] = ghevPmShutdown; // set up device notifications for(pdl = gpDeviceLists; pdl != NULL && dwNumEvents < dim(hEvents); pdl = pdl->pNext) { hEvents[dwNumEvents++] = pdl->hMsgQ; pdl->hnClass = RequestDeviceNotifications(pdl->pGuid, pdl->hMsgQ, TRUE); if(pdl->hnClass == NULL) { PMLOGMSG(ZONE_WARN, (_T("%s: RequestDeviceNotifications() failed %d\r\n"), pszFname, GetLastError())); } } DEBUGCHK(dwNumEvents > 1); // we're up and running SetEvent(hevReady); // Wait for Initalization complete. HANDLE hInit[2] = {ghevPowerManagerReady, ghevPmShutdown}; fDone = (WaitForMultipleObjects(_countof(hInit), hInit, FALSE, INFINITE)!= WAIT_OBJECT_0); // wait for new devices to arrive while(!fDone) { dwStatus = WaitForMultipleObjects(dwNumEvents, hEvents, FALSE, INFINITE); if(dwStatus == (WAIT_OBJECT_0 + 0)) { PMLOGMSG(ZONE_WARN, (_T("%s: shutdown event set\r\n"), pszFname)); fDone = TRUE; } else if(dwStatus > WAIT_OBJECT_0 && dwStatus <= (WAIT_OBJECT_0 + MAXIMUM_WAIT_OBJECTS)) { dwStatus -= WAIT_OBJECT_0; fOk = ProcessPnPMsgQueue(hEvents[dwStatus]); if(!fOk) { PMLOGMSG(ZONE_WARN, (_T("%s: ProcessPnPMsgQueue(0x%08x) failed\r\n"), pszFname, hEvents[dwStatus])); } } else { PMLOGMSG(ZONE_WARN, (_T("%s: WaitForMultipleObjects() returned %d, status is %d\r\n"), pszFname, dwStatus, GetLastError())); fDone = TRUE; break; } } // release resources for(pdl = gpDeviceLists; pdl != NULL; pdl = pdl->pNext) { if(pdl->hnClass != NULL) StopDeviceNotifications(pdl->hnClass); } // all done PMLOGMSG(ZONE_INIT | ZONE_WARN, (_T("-%s: exiting\r\n"), pszFname)); return 0; }