std::size_t PipeIODevice::onRead(char* buffer, std::size_t count, bool& eof) { if( Read != _mode ) throw IOError( PT_ERROR_MSG("Could not read from write only pipe") ); DWORD readBytes = 0; DWORD flags = 0; eof = false; DWORD timeout = _timeout == EventLoop::WaitInfinite ? INFINITE : static_cast<std::size_t>(_timeout); if(_bufferSize) { readBytes = _bufferSize; } else if ( FALSE == ReadMsgQueue(handle(), &_buffer[0], _msgSize, &readBytes, timeout, &flags) ) { throw IOError("ReadMsgQueue failed"); } memcpy(buffer, &_buffer[0], count); _bufferSize = 0; if (count >= readBytes) return readBytes; std::vector<char>::iterator beginData = (_buffer.begin() + count); std::vector<char>::iterator endData = (_buffer.begin() + readBytes); std::copy(beginData, endData, _buffer.begin()); _bufferSize = (readBytes - count); return count; }
std::size_t PipeIODevice::onEndRead(EventLoop& loop, char* buffer, std::size_t n, bool& eof) { loop.selector().disable(_ioh); DWORD readBytes = 0; DWORD flags = 0; eof = false; // TODO: can we receive EOF? if (_bufferSize) { readBytes = _bufferSize; } else if ( FALSE == ReadMsgQueue(handle(), &_buffer[0], _msgSize, &readBytes, INFINITE, &flags) ) { throw IOError( PT_ERROR_MSG("Could not read from message queue handle") ); } DWORD bytesToCopy = std::min<DWORD>(_rbuflen, readBytes); memcpy(_rbuf, &_buffer[0], bytesToCopy); _bufferSize = 0; if (_rbuflen >= readBytes) return readBytes; std::vector<char>::iterator beginData = (_buffer.begin() + bytesToCopy); std::vector<char>::iterator endData = (_buffer.begin() + readBytes); std::copy(beginData, endData, _buffer.begin()); _bufferSize = (readBytes - bytesToCopy); return bytesToCopy; }
// -------------------------------------------------------------------- BOOL ReadPnpMsgQueue(HANDLE hQueue, PDEVDETAIL pDevDetail, DWORD dwTimeout) // -------------------------------------------------------------------- { DWORD dwRead = 0; DWORD dwFlags =0; return ReadMsgQueue(hQueue, pDevDetail, QUEUE_ITEM_SIZE, &dwRead, dwTimeout, &dwFlags); }
// this routine reads device notifications from a message queue and updates // the PM's internal tables appropriately. BOOL ProcessPnPMsgQueue(HANDLE hMsgQ) { BOOL fOk = FALSE; UCHAR deviceBuf[PNP_QUEUE_SIZE]; DWORD iBytesInQueue = 0; DWORD dwFlags = 0; SETFNAME(_T("ProcessPnPMsgQueue")); // read a message from the message queue -- it should be a device advertisement memset(deviceBuf, 0, PNP_QUEUE_SIZE); if ( !ReadMsgQueue(hMsgQ, deviceBuf, PNP_QUEUE_SIZE, &iBytesInQueue, 0, &dwFlags)) { // nothing in the queue PMLOGMSG(ZONE_WARN, (_T("%s: ReadMsgQueue() failed %d\r\n"), pszFname, GetLastError())); } else if(iBytesInQueue >= sizeof(DEVDETAIL)) { // process the message PDEVDETAIL pDevDetail = (PDEVDETAIL) deviceBuf; DWORD dwMessageSize = sizeof(DEVDETAIL) + pDevDetail->cbName; // check for overlarge names if(pDevDetail->cbName > ((PNP_MAX_NAMELEN - 1) * sizeof(pDevDetail->szName[0]))) { PMLOGMSG(ZONE_WARN, (_T("%s: device name longer than %d characters\r\n"), pszFname, PNP_MAX_NAMELEN - 1)); } else { // convert the device name to lower case int i; for(i = 0; i < (PNP_MAX_NAMELEN - 1) && pDevDetail->szName[i] != 0; i++) { pDevDetail->szName[i] = _totlower(pDevDetail->szName[i]); } pDevDetail->szName[i] = 0; // add or remove the device -- note that a particular interface may be // advertised more than once, so these routines must handle that possibility. if(pDevDetail->fAttached) { AddDevice(&pDevDetail->guidDevClass, pDevDetail->szName, NULL, NULL); } else { RemoveDevice(&pDevDetail->guidDevClass, pDevDetail->szName); } fOk = TRUE; } } else { // not enough bytes for a message PMLOGMSG(ZONE_WARN, (_T("%s: got runt message (%d bytes)\r\n"), pszFname, iBytesInQueue)); } return fOk; }
static void checkDeviceNotificationQueue(HANDLE& queue) { const DWORD maxBufLen = sizeof(DEVDETAIL) + MAX_DEVCLASS_NAMELEN; char buf[maxBufLen]; DWORD bytesRead; DWORD flags; while (ReadMsgQueue(queue, &buf, maxBufLen, &bytesRead, 0, &flags)) { DEVDETAIL* detail = reinterpret_cast<DEVDETAIL*>(buf); if (detail->fAttached) { wprintf(L"\nDevice attached: %s\n", detail->szName); } else { wprintf(L"\nDevice detached: %s\n", detail->szName); } } }
DWORD msgThread(LPVOID lpParam){ HWND hWnd = (HWND)lpParam; hwndMsg=hWnd; DEBUGMSG(1,(L"Waiting for Bluetooth notifications with hwnd=%i...\n", hWnd)); nclog(L"%s: Waiting for Bluetooth notifications...\n", logDateTime()); TCHAR szMsg[MAX_PATH]; wsprintf(szMsg, L"\r\n%s: Waiting for Bluetooth notifications...", logDateTime()); printMsg(szMsg, hWnd); BTEVENT btEvent; DWORD dwBytesRead; DWORD dwFlags; BOOL fRet; while (FALSE == bStop) { DWORD dwWait = WaitForSingleObject (hMsgQ, 5000);//wait up to 5 seconds INFINITE); switch (dwWait){ case WAIT_OBJECT_0: // We have got a Bluetooth event! dwFlags = 0; dwBytesRead = 0; fRet = ReadMsgQueue (hMsgQ, &btEvent, sizeof(BTEVENT), &dwBytesRead, 10, &dwFlags); if (! fRet) { DEBUGMSG(1,(L"Error - Failed to read message from queue!\n")); //bStop=TRUE; } else { dumpBTevent(btEvent, hWnd); } break; case WAIT_TIMEOUT: break; case WAIT_ABANDONED: DEBUGMSG(1,(L"Error - Unexpected return value from WaitForSingleObject!\n")); //bStop=TRUE; break; case WAIT_FAILED: DEBUGMSG(1,(L"Error - Unexpected return value from WaitForSingleObject!\n")); //bStop=TRUE; break; }//switch }//while return 0; }
void ProcessPowerNotification(HANDLE hMsgQ) { union { UCHAR buf[QUEUE_SIZE]; POWER_BROADCAST powerBroadcast; } u; int iBytesInQueue; DWORD dwFlags = 0; int dwCount = 0; LPTSTR pszFname = _T("PMMON!ProcessPowerNotification"); iBytesInQueue = 0; memset(u.buf, 0, QUEUE_SIZE); if ( !ReadMsgQueue(hMsgQ, u.buf, QUEUE_SIZE, &iBytesInQueue, INFINITE, // Timeout &dwFlags)) { DWORD dwErr = GetLastError(); RetailPrint (TEXT("%s: ReadMsgQueue: ERROR:%d\n"), pszFname, dwErr); ASSERT(0); } else if(iBytesInQueue >= sizeof(POWER_BROADCAST)) { // // process power notifications // PPOWER_BROADCAST pB = &u.powerBroadcast; dwFlags = pB->Flags; RetailPrint (TEXT("%s: *** Power Notification @ Tick:%u, Count:%d***\n"), pszFname, GetTickCount(), dwCount++); switch (pB->Message) { case PBT_TRANSITION: RetailPrint (TEXT("%s:\tPBT_TRANSITION to system power state: '%s'\n"), pszFname, pB->SystemPowerState); RetailPrint (TEXT("%s:\t0x%08x "), pszFname, dwFlags); { struct { DWORD dwFlag; LPCTSTR pszFlagName; } sFlagInfo[] = { FLAGINFO(POWER_STATE_ON), FLAGINFO(POWER_STATE_OFF), FLAGINFO(POWER_STATE_CRITICAL), FLAGINFO(POWER_STATE_BOOT), FLAGINFO(POWER_STATE_IDLE), FLAGINFO(POWER_STATE_SUSPEND), FLAGINFO(POWER_STATE_RESET), FLAGINFO(POWER_STATE_PASSWORD), }; int i; // display each bit that's in the mask for(i = 0; i < dim(sFlagInfo); i++) { if((dwFlags & sFlagInfo[i].dwFlag) != 0) { RetailPrint (TEXT("%s "), sFlagInfo[i].pszFlagName); dwFlags &= ~sFlagInfo[i].dwFlag; // mask off the bit } } if(dwFlags != 0) { RetailPrint (TEXT("***UNKNOWN***")); } } RetailPrint (TEXT("\r\n")); break; case PBT_RESUME: RetailPrint (TEXT("%s:\tPBT_RESUME\n"), pszFname); break; case PBT_POWERSTATUSCHANGE: RetailPrint (TEXT("%s:\tPBT_POWERSTATUSCHANGE\n"), pszFname); break; case PBT_POWERINFOCHANGE: { PPOWER_BROADCAST_POWER_INFO ppbpi = (PPOWER_BROADCAST_POWER_INFO) pB->SystemPowerState; RetailPrint (TEXT("%s:\tPBT_POWERINFOCHANGE\n"), pszFname); RetailPrint (TEXT("%s:\t\tAC line status %u, battery flag %u, backup flag %u, %d levels\n"), pszFname, ppbpi->bACLineStatus, ppbpi->bBatteryFlag, ppbpi->bBackupBatteryFlag, ppbpi->dwNumLevels); RetailPrint (TEXT("%s:\t\tbattery life %d, backup life %d\n"), pszFname, ppbpi->bBatteryLifePercent, ppbpi->bBackupBatteryLifePercent); RetailPrint (TEXT("%s:\t\tlifetime 0x%08x, full lifetime 0x%08x\n"), pszFname, ppbpi->dwBatteryLifeTime, ppbpi->dwBatteryFullLifeTime); RetailPrint (TEXT("%s:\t\tbackup lifetime 0x%08x, backup full lifetime 0x%08x\n"), pszFname, ppbpi->dwBackupBatteryLifeTime, ppbpi->dwBackupBatteryFullLifeTime); } break; default: RetailPrint (TEXT("%s:\tUnknown Message:%d\n"), pszFname, pB->Message); break; } RetailPrint (TEXT("%s:\tMessage: 0x%x\n"), pszFname, pB->Message); RetailPrint (TEXT("%s:\tFlags: 0x%x\n"), pszFname, pB->Flags); RetailPrint (TEXT("%s:\tdwLen: %d\n"), pszFname, pB->Length); RetailPrint (TEXT("%s:***********************\n"), pszFname); } else { RetailPrint (TEXT("%s:\tReceived short message: %d bytes\n"), pszFname, iBytesInQueue); ASSERT(0); } }
void ProcessDeviceNotification(HANDLE hMsgQ) { union { UCHAR deviceBuf[PNP_QUEUE_SIZE]; DEVDETAIL devDetail; } u; DWORD iBytesInQueue = 0; DWORD dwFlags = 0; LPTSTR pszFname = _T("PMMON!ProcessDeviceNotification"); // read a message from the message queue -- it should be a device advertisement memset(u.deviceBuf, 0, PNP_QUEUE_SIZE); if ( !ReadMsgQueue(hMsgQ, u.deviceBuf, PNP_QUEUE_SIZE, &iBytesInQueue, 0, &dwFlags)) { // nothing in the queue RetailPrint (_T("%s: ReadMsgQueue() failed %d\r\n"), pszFname, GetLastError()); } else if(iBytesInQueue >= sizeof(DEVDETAIL)) { // process the message PDEVDETAIL pDevDetail = &u.devDetail; //DWORD dwMessageSize = sizeof(DEVDETAIL) + pDevDetail->cbName; // check for overlarge names if(pDevDetail->cbName > ((PNP_MAX_NAMELEN - 1) * sizeof(pDevDetail->szName[0]))) { RetailPrint (_T("%s: device name longer than %d characters\r\n"), pszFname, PNP_MAX_NAMELEN - 1); } else { LPCTSTR pszName = pDevDetail->szName; LPCGUID guidDevClass = &pDevDetail->guidDevClass; TCHAR szClassDescription[MAX_PATH]; TCHAR szClassName[MAX_PATH]; HKEY hk; DWORD dwStatus; // format the class name _stprintf(szClassName, _T("{%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x}"), 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]); // (inefficiently) look up the class description whenever a device registers wsprintf(szClassDescription, _T("%s\\Interfaces"), PWRMGR_REG_KEY); dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szClassDescription, 0, 0, &hk); if(dwStatus == ERROR_SUCCESS) { DWORD dwSize = sizeof(szClassDescription); dwStatus = RegQueryValueEx(hk, szClassName, NULL, NULL, (LPBYTE) szClassDescription, &dwSize); RegCloseKey(hk); } if(dwStatus != ERROR_SUCCESS) { _tcscpy(szClassDescription, (_T("<unknown class>"))); } RetailPrint (_T("%s: device '%s' %s class %s ('%s')\r\n"), pszFname, pszName, pDevDetail->fAttached ? _T("joining") : _T("leaving"), szClassName, szClassDescription); } } else { // not enough bytes for a message RetailPrint (_T("%s: got runt message (%d bytes)\r\n"), pszFname, iBytesInQueue); } }
void PowerMonitorThread() { MSGQUEUEOPTIONS PowerMsgQOptions = {0,}; HANDLE hPowerMsgQ = NULL; HANDLE hPowerNotifications = NULL; HANDLE rgHandles[2] = {0}; PowerMsgQOptions.dwSize = sizeof(MSGQUEUEOPTIONS); PowerMsgQOptions.dwFlags = MSGQUEUE_NOPRECOMMIT ; PowerMsgQOptions.dwMaxMessages = 0; PowerMsgQOptions.cbMaxMessage = sizeof(POWER_BROADCAST) + sizeof(POWER_BROADCAST_POWER_INFO); PowerMsgQOptions.bReadAccess = TRUE; hPowerMsgQ = CreateMsgQueue(NULL, &PowerMsgQOptions); if( hPowerMsgQ == NULL ) { RETAILMSG(1,(L"[WSM] CreateMsgQueue Failed(%d) \r\n", GetLastError() )); goto Exit; } // Request power notifications hPowerNotifications = RequestPowerNotifications(hPowerMsgQ, PBT_TRANSITION | PBT_RESUME | PBT_POWERINFOCHANGE); if( hPowerNotifications == NULL ) { RETAILMSG(1,(L"[WSM] RequestPowerNotifications Failed(%d) \r\n", GetLastError() )); goto Exit; } rgHandles[0] = hPowerMsgQ; rgHandles[1] = g_hEventClosePwrMonThread; // 1번째 핸들이 아닌경우에는 이 스레드는 Close 된다. (g_hEventClosePwrMonThread 이벤트 인경우 Close) while( WaitForMultipleObjects(2, rgHandles, FALSE, INFINITE) == WAIT_OBJECT_0 ) { DWORD cbRead; DWORD dwFlags; POWER_BROADCAST *ppb = (POWER_BROADCAST*) new BYTE[sizeof(POWER_BROADCAST) + sizeof(POWER_BROADCAST_POWER_INFO)]; // loop through in case there is more than 1 msg. while(ReadMsgQueue(hPowerMsgQ, ppb, sizeof(POWER_BROADCAST) + sizeof(POWER_BROADCAST_POWER_INFO), &cbRead, 0, &dwFlags)) { if( ppb->Message == PBT_TRANSITION ) { if( ppb->Length && wcscmp(ppb->SystemPowerState, L"unattended") == 0 ) { if ( g_bCheckedUnattendedMode == TRUE ) { // Create RepeatSysIdleTimerResetThread g_bRunningRepeatSysIdleTimerResetThread = TRUE; g_hRepeatSysIdleTimerResetThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)RepeatSysIdleTimerResetThread, NULL, 0, NULL); if( g_hRepeatSysIdleTimerResetThread == INVALID_HANDLE_VALUE ) { RETAILMSG(1, (TEXT("[ERR] Can't create g_hRepeatSysIdleTimerResetThread \r\n") )); g_hRepeatSysIdleTimerResetThread = NULL; } } } else { // Close RepeatSysIdleTimerResetThread g_bRunningRepeatSysIdleTimerResetThread = FALSE; if( g_hRepeatSysIdleTimerResetThread ) { if( WaitForSingleObject(g_hRepeatSysIdleTimerResetThread, 1000) == WAIT_TIMEOUT ) { DWORD dwCode = 0; GetExitCodeThread(g_hRepeatSysIdleTimerResetThread, &dwCode); if( dwCode == STILL_ACTIVE ) { RETAILMSG(1, (TEXT("[WSM] g_hRepeatSysIdleTimerResetThread Terminate \r\n") )); TerminateThread(g_hRepeatSysIdleTimerResetThread, 0); } } CloseHandle(g_hRepeatSysIdleTimerResetThread); g_hRepeatSysIdleTimerResetThread = NULL; } } } } delete[] ppb; } RETAILMSG(1,(L"[WSM] PowerMonitorThread End \r\n")); Exit: if (hPowerNotifications) { StopPowerNotifications(hPowerNotifications); hPowerNotifications = NULL; } if (hPowerMsgQ) { CloseMsgQueue(hPowerMsgQ); hPowerMsgQ = NULL; } return; }
//*************************************************************************** // Function Name: PowerNotificationThread // // Purpose: listens for power change notifications // DWORD PowerNotificationThread(LPVOID pVoid) { // size of a POWER_BROADCAST message DWORD cbPowerMsgSize = sizeof POWER_BROADCAST + (MAX_PATH * sizeof TCHAR); // Initialize our MSGQUEUEOPTIONS structure MSGQUEUEOPTIONS mqo; mqo.dwSize = sizeof(MSGQUEUEOPTIONS); mqo.dwFlags = MSGQUEUE_NOPRECOMMIT; mqo.dwMaxMessages = 4; mqo.cbMaxMessage = cbPowerMsgSize; mqo.bReadAccess = TRUE; // Create a message queue to receive power notifications HANDLE hPowerMsgQ = CreateMsgQueue(NULL, &mqo); if (NULL == hPowerMsgQ) { RETAILMSG(1, (L"CreateMsgQueue failed: %x\n", GetLastError())); goto Error; } // Request power notifications HANDLE hPowerNotifications = RequestPowerNotifications(hPowerMsgQ, PBT_TRANSITION | PBT_RESUME | PBT_POWERINFOCHANGE); if (NULL == hPowerNotifications) { RETAILMSG(1, (L"RequestPowerNotifications failed: %x\n", GetLastError())); goto Error; } HANDLE rgHandles[2] = {0}; rgHandles[0] = hPowerMsgQ; rgHandles[1] = g_hEventShutDown; // Wait for a power notification or for the app to exit while(WaitForMultipleObjects(2, rgHandles, FALSE, INFINITE) == WAIT_OBJECT_0) { DWORD cbRead; DWORD dwFlags; POWER_BROADCAST *ppb = (POWER_BROADCAST*) new BYTE[cbPowerMsgSize]; // loop through in case there is more than 1 msg while(ReadMsgQueue(hPowerMsgQ, ppb, cbPowerMsgSize, &cbRead, 0, &dwFlags)) { switch (ppb->Message) { case PBT_TRANSITION: RETAILMSG(1,(L"Power Notification Message: PBT_TRANSITION\n")); RETAILMSG(1,(L"Flags: %lx", ppb->Flags)); RETAILMSG(1,(L"Length: %d", ppb->Length)); if (ppb->Length) { RETAILMSG(1,(L"SystemPowerState: %s\n", ppb->SystemPowerState)); } break; case PBT_RESUME: RETAILMSG(1,(L"Power Notification Message: PBT_RESUME\n")); break; case PBT_POWERINFOCHANGE: { RETAILMSG(1,(L"Power Notification Message: PBT_POWERINFOCHANGE\n")); // PBT_POWERINFOCHANGE message embeds a // POWER_BROADCAST_POWER_INFO structure into the // SystemPowerState field PPOWER_BROADCAST_POWER_INFO ppbpi = (PPOWER_BROADCAST_POWER_INFO) ppb->SystemPowerState; if (ppbpi) { RETAILMSG(1,(L"Length: %d", ppb->Length)); RETAILMSG(1,(L"BatteryLifeTime = %d\n",ppbpi->dwBatteryLifeTime)); RETAILMSG(1,(L"BatterFullLifeTime = %d\n", ppbpi->dwBatteryFullLifeTime)); RETAILMSG(1,(L"BackupBatteryLifeTime = %d\n", ppbpi->dwBackupBatteryLifeTime)); RETAILMSG(1,(L"BackupBatteryFullLifeTime = %d\n", ppbpi->dwBackupBatteryFullLifeTime)); RETAILMSG(1,(L"ACLineStatus = %d\n",ppbpi->bACLineStatus)); RETAILMSG(1,(L"BatteryFlag = %d\n",ppbpi->bBatteryFlag)); RETAILMSG(1,(L"BatteryLifePercent = %d\n", ppbpi->bBatteryLifePercent)); RETAILMSG(1,(L"BackupBatteryFlag = %d\n", ppbpi->bBackupBatteryFlag)); RETAILMSG(1,(L"BackupBatteryLifePercent = %d\n", ppbpi->bBackupBatteryLifePercent)); } break; } default: break; } UpdatePowerState(); } delete[] ppb; } Error: if (hPowerNotifications) StopPowerNotifications(hPowerNotifications); if (hPowerMsgQ) CloseMsgQueue(hPowerMsgQ); return NULL; }