void run() { WNDCLASS windowClass = {}; LPCWSTR SzWndClass = TEXT("MINWINAPP"); windowClass.lpfnWndProc = &on_win_event; windowClass.lpszClassName = SzWndClass; UnregisterClass(SzWndClass, nullptr); if (!RegisterClass(&windowClass)) LOG_WARNING("RegisterClass failed."); _data.hWnd = CreateWindow(SzWndClass, nullptr, 0, 0, 0, 0, 0, HWND_MESSAGE, nullptr, nullptr, &_data); if (!_data.hWnd) throw winapi_error("CreateWindow failed"); MSG msg; while (!_data._stopped) { if (PeekMessage(&msg, _data.hWnd, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } else // Yield CPU resources, as this is required for connect/disconnect events only std::this_thread::sleep_for(std::chrono::milliseconds(50)); } UnregisterDeviceNotification(_data.hdevnotifyHW); UnregisterDeviceNotification(_data.hdevnotifyUVC); DestroyWindow(_data.hWnd); }
// // unregister a service as device-notification listener // void LSLib_UnregisterDevNotification(HDEVNOTIFY hSCSIIfNtf, HDEVNOTIFY hVolNtf) { if(UnregisterDeviceNotification(hSCSIIfNtf) == FALSE) { PrintErrorCode("[LDServ] Unregister SCSI Adapter Interface Notification fail... ", GetLastError()); } if(UnregisterDeviceNotification(hVolNtf) == FALSE) { PrintErrorCode("[LDServ] Unregister Logical Volume Notification fail... ", GetLastError()); } }
LRESULT CALLBACK win_proc(HWND win, UINT message, WPARAM w_param, LPARAM l_param) { DEV_BROADCAST_HDR *hdr = (DEV_BROADCAST_HDR *) l_param; switch(message) { case WM_DESTROY: if(notification_handle_hub) UnregisterDeviceNotification(notification_handle_hub); if(notification_handle_dev) UnregisterDeviceNotification(notification_handle_dev); PostQuitMessage(0); break; case WM_SIZE: on_size(LOWORD(l_param), HIWORD(l_param)); break; case WM_COMMAND: switch(LOWORD(w_param)) { case ID_EXIT: PostQuitMessage(0); break; case ID_REFRESH: on_refresh(); break; default: return DefWindowProc(win, message, w_param, l_param ); } break; case WM_DEVICECHANGE: switch(w_param) { case DBT_DEVICEREMOVECOMPLETE: if(hdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) on_refresh(); break; case DBT_DEVICEARRIVAL: if(hdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) on_refresh(); break; default: ; } break; default: return DefWindowProc(win, message, w_param, l_param); } return 0; }
void _glfwPlatformTerminate(void) { if (_glfw.win32.deviceNotificationHandle) UnregisterDeviceNotification(_glfw.win32.deviceNotificationHandle); if (_glfw.win32.helperWindowHandle) DestroyWindow(_glfw.win32.helperWindowHandle); _glfwUnregisterWindowClassWin32(); // Restore previous foreground lock timeout system setting SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, UIntToPtr(_glfw.win32.foregroundLockTimeout), SPIF_SENDCHANGE); free(_glfw.win32.clipboardString); free(_glfw.win32.rawInput); _glfwTerminateWGL(); _glfwTerminateEGL(); _glfwTerminateJoysticksWin32(); freeLibraries(); }
INT_PTR WINAPI messageCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_DEVICECHANGE: if (wParam == DBT_DEVICEARRIVAL || wParam == DBT_DEVICEREMOVECOMPLETE) { // Wait for 30 frames, send refresh mustRefreshDevices = 30; } break; case WM_CLOSE: UnregisterDeviceNotification(hDeviceNotify); DestroyWindow(hWnd); diAvailable = false; // Releasing resources to avoid crashes for (auto it : joysticks) { if (it.second) { it.second->Unacquire(); it.second->Release(); } } joysticks.clear(); if (di) { di->Release(); } di = NULL; break; default: // Send all other messages on to the default windows handler. return DefWindowProc(hWnd, message, wParam, lParam); } return 1; }
DWORD WINAPI ServiceCtrlHandlerEx(DWORD dwOpcode, DWORD dwEventType, LPVOID lpEventData, LPVOID /*lpContext*/) { DWORD dwRes = ERROR_CALL_NOT_IMPLEMENTED; switch (dwOpcode) { case SERVICE_CONTROL_STOP: DebugOut("SERVICE_CONTROL_STOP\n"); if (hDevNotify) UnregisterDeviceNotification(hDevNotify); ServiceStatus.dwWin32ExitCode = 0; ServiceStatus.dwCurrentState = SERVICE_STOPPED; ServiceStatus.dwCheckPoint = 0; ServiceStatus.dwWaitHint = 0; if (gpSid) free(gpSid); dwRes = NO_ERROR; break; case SERVICE_CONTROL_INTERROGATE: DebugOut("SERVICE_CONTROL_INTERROGATE\n"); dwRes = NO_ERROR; break; case SERVICE_CONTROL_DEVICEEVENT: DebugOut("SERVICE_CONTROL_DEVICEEVENT"); DeviceEventNotify(dwEventType, lpEventData); dwRes = NO_ERROR; break; } if (!SetServiceStatus(hServiceStatus, &ServiceStatus)) { // Send current status. DebugOut("SetServiceStatus failed! (LastError=0x%x)\n", GetLastError()); } return dwRes; }
void UsbSerial::usbClose( ) { if( deviceOpen ) { QMutexLocker locker( &usbMutex ); // Linux Only #if (defined(Q_WS_LINUX)) #endif //Mac-only #ifdef Q_WS_MAC ::close( deviceHandle ); deviceHandle = -1; deviceOpen = false; #endif //----------------------------------------------------------------- // Windows-only usbClose( ) //----------------------------------------------------------------- #ifdef Q_WS_WIN CloseHandle( deviceHandle ); deviceHandle = INVALID_HANDLE_VALUE; deviceOpen = false; UnregisterDeviceNotification( notificationHandle ); #endif //Windows-only UsbSerial::close( ) //messageInterface->messageThreadSafe( "Usb> Make Controller disconnected." ); } }
void Gamepad_Windows::destroy() { if (_reader_thread_handle) { DWORD errcode = ERROR_OBJECT_NOT_FOUND; if (_input_received_event) SetEvent(_input_received_event); if (_thread_exit_event) errcode = SignalObjectAndWait(_thread_exit_event, _reader_thread_handle, 1000, false); if (errcode) TerminateThread(_reader_thread_handle, errcode); CloseHandle(_reader_thread_handle); _reader_thread_handle = NULL; } if (_input_received_event) { CloseHandle(_input_received_event); _input_received_event = NULL; } if (_thread_exit_event) { CloseHandle(_thread_exit_event); _thread_exit_event = NULL; } if (_preparsed) { hid.HidD_FreePreparsedData(_preparsed); _preparsed = NULL; } if (_notif_handle != NULL) { UnregisterDeviceNotification(_notif_handle); _notif_handle = NULL; } if (_handle != INVALID_HANDLE_VALUE) { CloseHandle(_handle); _handle = INVALID_HANDLE_VALUE; } }
void hid_free_event_monitor(hid_event_monitor* monitor) { BOOL ret = FALSE; if (monitor->hwnd) { ret = DestroyWindow(monitor->hwnd); if (!ret) { DWORD last_error = GetLastError(); printf("hid_free_event_monitor failed, DestroyWindow failed, last error: %ul", last_error); } } if (monitor->dev_notify) { ret = UnregisterDeviceNotification(monitor->dev_notify); if (!ret) { DWORD last_error = GetLastError(); printf("hid_free_event_monitor failed, UnregisterDeviceNotification failed, last error: %ul", last_error); } } if (monitor->proc_event.device_info) { free(monitor->proc_event.device_info->path); free(monitor->proc_event.device_info->serial_number); free(monitor->proc_event.device_info->manufacturer_string); free(monitor->proc_event.device_info->product_string); free(monitor->proc_event.device_info); } free(monitor); }
BOOL CPnpEventConsumerWindow::OnDeviceChange( UINT EventType, PDEV_BROADCAST_HANDLE Dbch) { switch (EventType) { case DBT_DEVICEREMOVECOMPLETE: { ATLVERIFY( m_DevNotifyHandles.Remove(Dbch->dbch_hdevnotify) ); printf("Unregistering DevNotifyHandle=%p\n", Dbch->dbch_hdevnotify); ATLVERIFY( UnregisterDeviceNotification(Dbch->dbch_hdevnotify) ); } break; case DBT_CUSTOMEVENT: if (IsEqualGUID(Dbch->dbch_eventguid, GUID_NDASPORT_PNP_NOTIFICATION)) { PNDASPORT_PNP_NOTIFICATION ndasportNotification = reinterpret_cast<PNDASPORT_PNP_NOTIFICATION>(Dbch->dbch_data); OnNdasPortEvent(ndasportNotification); } else if (IsEqualGUID(Dbch->dbch_eventguid, GUID_NDAS_ATA_LINK_EVENT)) { PNDAS_ATA_LINK_EVENT ndasAtaLinkEvent = reinterpret_cast<PNDAS_ATA_LINK_EVENT>(Dbch->dbch_data); OnNdasAtaLinkEvent(ndasAtaLinkEvent); } else if (IsEqualGUID(Dbch->dbch_eventguid, NDAS_DLU_EVENT_GUID)) { PNDAS_DLU_EVENT ndasDluEvent = reinterpret_cast<PNDAS_DLU_EVENT>(Dbch->dbch_data); OnNdasDluEvent(ndasDluEvent); } else if (IsEqualGUID(Dbch->dbch_eventguid, GUID_IO_VOLUME_MOUNT)) { // printf("Volume is mounted, handle=%p\n", Dbch->dbch_handle); } else { OLECHAR guidString[64] = {0}; StringFromGUID2( Dbch->dbch_eventguid, guidString, 64); if (-1 != Dbch->dbch_nameoffset) { printf("Unknown %s (%ls)", ((PUCHAR)Dbch) + Dbch->dbch_nameoffset, guidString); } else { printf("Unknown %ls", guidString); } } } return TRUE; }
void OnClose(HWND /*hwnd*/) { if (g_hdevnotify) { UnregisterDeviceNotification(g_hdevnotify); } PostQuitMessage(0); }
bool CDirectoryWatcher::CDirWatchInfo::CloseDirectoryHandle() { bool b = m_hDir.CloseHandle(); if (m_hDevNotify) { UnregisterDeviceNotification(m_hDevNotify); m_hDevNotify = NULL; } return b; }
void CPnpEventConsumerWindow::OnDestroy() { int count = m_DevNotifyHandles.GetSize(); for (int i = 0; i < count; ++i) { printf("Unregistering DevNotifyHandle=%p\n", m_DevNotifyHandles[i]); ATLVERIFY( UnregisterDeviceNotification(m_DevNotifyHandles[i]) ); } SetMsgHandled(FALSE); PostQuitMessage(0); }
QextSerialEnumerator::~QextSerialEnumerator( ) { #ifdef Q_OS_MAC IONotificationPortDestroy( notificationPortRef ); #elif (defined Q_OS_WIN) if( notificationHandle ) UnregisterDeviceNotification( notificationHandle ); #ifdef QT_GUI_LIB if( notificationWidget ) delete notificationWidget; #endif #endif }
bool CDirectoryWatcher::CDirWatchInfo::CloseDirectoryHandle() { bool b = TRUE; if( m_hDir != INVALID_HANDLE_VALUE ) { b = !!CloseHandle(m_hDir); m_hDir = INVALID_HANDLE_VALUE; } if (m_hDevNotify != INVALID_HANDLE_VALUE) { UnregisterDeviceNotification(m_hDevNotify); } return b; }
//----------------------------------------------------------------------------- void CWindowMinMaxSubclass::UnsubclassWindow() { #ifdef XP_WIN if (m_prevWndProc == NULL) return; SetWindowLong(m_hwnd, GWL_WNDPROC, (LONG)m_prevWndProc); SetWindowLong(m_hwnd, GWL_USERDATA, 0); m_prevWndProc = NULL; if(m_hDevNotify != NULL) { UnregisterDeviceNotification(m_hDevNotify); m_hDevNotify = NULL; } #endif }
HRESULT AbstractGattService::StopMessagePump() { HRESULT hr = S_OK; // // Unregister for device change notifications // if (NULL != m_hDevNotification) { UnregisterDeviceNotification(m_hDevNotification); m_hDevNotification = NULL; } if (NULL != m_hMessagePumpThread) { // // Set the terminate event such that the message pump exists // SetEvent(m_hMessagePumpTerminate); // // Wait until the message pump thread exists // WaitForSingleObject(m_hMessagePumpThread, INFINITE); CloseHandle(m_hMessagePumpThread); m_hMessagePumpThread = NULL; CloseHandle(m_hMessagePumpTerminate); m_hMessagePumpTerminate = NULL; CloseHandle(m_hMessagePumpInitialized); m_hMessagePumpInitialized = NULL; } // destroy our hiden window if (NULL != m_hWnd) { DestroyWindow(m_hWnd); m_hWnd = NULL; } UnregisterClass(GATT_SERVICE_CLASSNAME, g_hInstance); return hr; }
void CService::terminate(DWORD error) { if (m_hDevNotify) { UnregisterDeviceNotification(m_hDevNotify); m_hDevNotify = NULL; } if (m_evTerminate) { CloseHandle(m_evTerminate); m_evTerminate = NULL; } if (m_StatusHandle) { SendStatusToSCM(SERVICE_STOPPED, error, 0, 0, 0); } delete m_pDev; }
HRESULT CNdasServiceDeviceEventHandler::RegisterDeviceInterfaceNotification( __in LPCGUID InterfaceGuid, __in LPCSTR TypeName) { HDEVNOTIFY devNotifyHandle; HRESULT hr = pRegisterDeviceInterfaceNotification( m_hRecipient, m_dwReceptionFlags, InterfaceGuid, &devNotifyHandle); if (FAILED(hr)) { XTLTRACE2(NDASSVC_PNP, TRACE_LEVEL_ERROR, "RegisterDeviceInterfaceNotification failed, type=%hs, hr=0x%X\n", TypeName, hr); return hr; } try { m_DeviceInterfaceNotifyHandles.push_back(devNotifyHandle); } catch (...) { XTLTRACE2(NDASSVC_PNP, TRACE_LEVEL_ERROR, "RegisterDeviceInterfaceNotification failed, " "C++ exception, type=%hs\n", TypeName); XTLVERIFY(UnregisterDeviceNotification(devNotifyHandle)); return E_FAIL; } return S_OK; }
void DeviceStatus::ShutDown() { OVR_ASSERT(hMessageWindow); if (!UnregisterDeviceNotification(hDeviceNotify)) { OVR_ASSERT_LOG(false, ("Failed to unregister device notification.")); } PostMessage(hMessageWindow, WM_CLOSE, 0, 0); while (hMessageWindow != NULL) { ProcessMessages(); Sleep(1); } if (!UnregisterClass(windowClassName, NULL)) { OVR_ASSERT_LOG(false, ("Failed to unregister window class.")); } }
static BOOL DoRegisterDeviceInterfaceToHwnd(HWND hWnd) { auto data = reinterpret_cast<extra_data*>(GetWindowLongPtr(hWnd, GWLP_USERDATA)); //===========================register HWmonitor events============================== const GUID classGuid = { 0x175695cd, 0x30d9, 0x4f87, 0x8b, 0xe3, 0x5a, 0x82, 0x70, 0xf4, 0x9a, 0x31 }; DEV_BROADCAST_DEVICEINTERFACE devBroadcastDeviceInterface; devBroadcastDeviceInterface.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); devBroadcastDeviceInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; devBroadcastDeviceInterface.dbcc_classguid = classGuid; devBroadcastDeviceInterface.dbcc_reserved = 0; data->hdevnotifyHW = RegisterDeviceNotification(hWnd, &devBroadcastDeviceInterface, DEVICE_NOTIFY_WINDOW_HANDLE); if (data->hdevnotifyHW == NULL) { LOG_WARNING("Register HW events Failed!\n"); return FALSE; } ////===========================register UVC events============================== DEV_BROADCAST_DEVICEINTERFACE di = { 0 }; di.dbcc_size = sizeof(di); di.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; di.dbcc_classguid = KSCATEGORY_CAPTURE; data->hdevnotifyUVC = RegisterDeviceNotification(hWnd, &di, DEVICE_NOTIFY_WINDOW_HANDLE); if (data->hdevnotifyUVC == nullptr) { UnregisterDeviceNotification(data->hdevnotifyHW); LOG_WARNING("Register UVC events Failed!\n"); return FALSE; } return TRUE; }
void Input::TerminateWindow() { // unregister from raw input mouse and keyboard events { RAWINPUTDEVICE devices[2]; devices[0].usUsagePage = HID_USAGE_PAGE_GENERIC; devices[0].usUsage = HID_USAGE_GENERIC_MOUSE; devices[0].dwFlags = RIDEV_REMOVE; devices[0].hwndTarget = NULL; devices[1].usUsagePage = HID_USAGE_PAGE_GENERIC; devices[1].usUsage = HID_USAGE_GENERIC_KEYBOARD; devices[1].dwFlags = RIDEV_REMOVE; devices[1].hwndTarget = NULL; RegisterRawInputDevices(devices, ARRAYSIZE(devices), sizeof(RAWINPUTDEVICE)); } UnregisterDeviceNotification(deviceNotification); DestroyWindow(window); }
HRESULT CNdasServiceDeviceEventHandler::UnregisterDeviceHandleNotification( __in HDEVNOTIFY DevNotifyHandle) { EnterCriticalSection(&m_DevNotifyMapSection); DevNotifyMap::iterator itr = m_DevNotifyMap.find(DevNotifyHandle); if (m_DevNotifyMap.end() == itr) { LeaveCriticalSection(&m_DevNotifyMapSection); return E_FAIL; } DEVICE_HANDLE_NOTIFY_DATA& ndata = itr->second; m_DevNotifyMap.erase(itr); LeaveCriticalSection(&m_DevNotifyMapSection); XTLVERIFY( UnregisterDeviceNotification(DevNotifyHandle) ); return S_OK; }
/*------------------------------------------------------------------------------*/ void AkindDI::Exit( void ) { if (m_hJoyDeviceNotify) { UnregisterDeviceNotification(m_hJoyDeviceNotify); m_hJoyDeviceNotify = NULL; } if ( m_pDInputKey != NULL ){ m_pDInputKey->Unacquire(); m_pDInputKey->Release(); m_pDInputKey = NULL; } for ( int i=0; i<m_JoyNum; i++ ){ if ( m_pDInputJoy[i] != NULL ){ m_pDInputJoy[i]->Unacquire(); m_pDInputJoy[i]->Release(); m_pDInputJoy[i] = NULL; } } if ( m_pDInput != NULL ){ m_pDInput->Release(); m_pDInput = NULL; } }
void UsbSerial::usbClose( ) { if( deviceOpen ) { // Linux Only #if (defined(Q_WS_LINUX)) #endif //Mac-only #ifdef Q_WS_MAC ::close( deviceHandle ); foundMakeController = false; deviceHandle = -1; deviceOpen = false; #endif //Windows-only #ifdef Q_WS_WIN CloseHandle( deviceHandle ); deviceHandle = INVALID_HANDLE_VALUE; deviceOpen = false; UnregisterDeviceNotification( deviceNotificationHandle ); #endif //Windows-only UsbSerial::close( ) messageInterface->message( 1, "Usb> Make Controller disconnected.\n" ); } }
static INT_PTR WINAPI DevNotifyWndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) { LRESULT retval = 1; static HDEVNOTIFY hDeviceNotify; DEV_BROADCAST_HDR *arrival; DEV_BROADCAST_VOLUME *volume; switch (message) { case WM_CREATE: if (!DoRegisterDeviceInterface( GUID_DEVINTERFACE_DISK, hWnd, &hDeviceNotify)) { perror("DoRegisterDeviceInterfaceToHwnd"); ExitThread(1); } break; case WM_DEVICECHANGE: { DEV_BROADCAST_DEVICEINTERFACE *b = (DEV_BROADCAST_DEVICEINTERFACE *) lParam; switch (wParam) { case DBT_DEVICEARRIVAL: arrival = (DEV_BROADCAST_HDR *) lParam; LogDebug("DBT_DEVICEARRIVAL: type %d", arrival->dbch_devicetype); if (arrival->dbch_devicetype == DBT_DEVTYP_VOLUME) { // New volume mounted. volume = (DEV_BROADCAST_VOLUME *) lParam; LogDebug("mask: 0x%x", volume->dbcv_unitmask); // Each bit corresponds to disk letter for the newly mounted volume. g_NewVolumeBitmask = volume->dbcv_unitmask; goto close; } break; case DBT_DEVICEREMOVECOMPLETE: LogDebug("DBT_DEVICEREMOVECOMPLETE"); break; case DBT_DEVNODES_CHANGED: LogDebug("DBT_DEVNODES_CHANGED"); break; default: LogWarning("Unknown device change: %d", wParam); break; } } break; close: case WM_CLOSE: if (!UnregisterDeviceNotification(hDeviceNotify)) { perror("UnregisterDeviceNotification"); } DestroyWindow(hWnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: // Send all other messages on to the default windows handler. retval = DefWindowProc(hWnd, message, wParam, lParam); break; } return retval; }
// NOTE: this function needs to call RegisterServiceCtrlHandlerEx and // SetServiceStatus in all circumstances if brickd is running as service static int generic_main(int log_to_file, int debug) { int exit_code = EXIT_FAILURE; const char *mutex_name = "Global\\Tinkerforge-Brick-Daemon-Single-Instance"; HANDLE mutex_handle = NULL; int mutex_error = 0; DWORD service_exit_code = NO_ERROR; int rc; char filename[1024]; int i; FILE *logfile = NULL; WSADATA wsa_data; DEV_BROADCAST_DEVICEINTERFACE notification_filter; HDEVNOTIFY notification_handle; mutex_handle = OpenMutex(SYNCHRONIZE, FALSE, mutex_name); if (mutex_handle == NULL) { rc = GetLastError(); if (rc == ERROR_ACCESS_DENIED) { rc = service_is_running(); if (rc < 0) { mutex_error = 1; // FIXME: set service_exit_code goto error_mutex; } else if (rc) { mutex_error = 1; service_exit_code = ERROR_SERVICE_ALREADY_RUNNING; log_error("Could not start as %s, another instance is already running as service", _run_as_service ? "service" : "console application"); goto error_mutex; } } if (rc != ERROR_FILE_NOT_FOUND) { mutex_error = 1; // FIXME: set service_exit_code rc += ERRNO_WINAPI_OFFSET; log_error("Could not open single instance mutex: %s (%d)", get_errno_name(rc), rc); goto error_mutex; } } if (mutex_handle != NULL) { mutex_error = 1; service_exit_code = ERROR_SERVICE_ALREADY_RUNNING; log_error("Could not start as %s, another instance is already running", _run_as_service ? "service" : "console application"); goto error_mutex; } mutex_handle = CreateMutex(NULL, FALSE, mutex_name); if (mutex_handle == NULL) { mutex_error = 1; // FIXME: set service_exit_code rc = ERRNO_WINAPI_OFFSET + GetLastError(); log_error("Could not create single instance mutex: %s (%d)", get_errno_name(rc), rc); goto error_mutex; } if (!_run_as_service && !SetConsoleCtrlHandler(console_ctrl_handler, TRUE)) { rc = ERRNO_WINAPI_OFFSET + GetLastError(); log_warn("Could not set console control handler: %s (%d)", get_errno_name(rc), rc); } if (log_to_file) { if (GetModuleFileName(NULL, filename, sizeof(filename)) == 0) { rc = ERRNO_WINAPI_OFFSET + GetLastError(); log_warn("Could not get module file name: %s (%d)", get_errno_name(rc), rc); } else { i = strlen(filename); if (i < 4) { log_warn("Module file name '%s' is too short", filename); } else { strcpy(filename + i - 3, "log"); logfile = fopen(filename, "a+"); if (logfile == NULL) { log_warn("Could not open logfile '%s'", filename); } else { log_set_file(logfile); } } } } if (debug) { log_set_level(LOG_CATEGORY_EVENT, LOG_LEVEL_DEBUG); log_set_level(LOG_CATEGORY_USB, LOG_LEVEL_DEBUG); log_set_level(LOG_CATEGORY_NETWORK, LOG_LEVEL_DEBUG); log_set_level(LOG_CATEGORY_HOTPLUG, LOG_LEVEL_DEBUG); log_set_level(LOG_CATEGORY_OTHER, LOG_LEVEL_DEBUG); } else { log_set_level(LOG_CATEGORY_EVENT, config_get_log_level(LOG_CATEGORY_EVENT)); log_set_level(LOG_CATEGORY_USB, config_get_log_level(LOG_CATEGORY_USB)); log_set_level(LOG_CATEGORY_NETWORK, config_get_log_level(LOG_CATEGORY_NETWORK)); log_set_level(LOG_CATEGORY_HOTPLUG, config_get_log_level(LOG_CATEGORY_HOTPLUG)); log_set_level(LOG_CATEGORY_OTHER, config_get_log_level(LOG_CATEGORY_OTHER)); } if (_run_as_service) { log_info("Brick Daemon %s started (as service)", VERSION_STRING); } else { log_info("Brick Daemon %s started", VERSION_STRING); } if (config_has_error()) { log_warn("Errors found in config file '%s', run with --check-config option for details", _config_filename); } // initialize service status error_mutex: if (_run_as_service) { if (service_init(service_control_handler) < 0) { // FIXME: set service_exit_code goto error; } if (!mutex_error) { // service is starting service_set_status(SERVICE_START_PENDING, NO_ERROR); } } if (mutex_error) { goto error; } // initialize WinSock2 if (WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0) { // FIXME: set service_exit_code rc = ERRNO_WINAPI_OFFSET + WSAGetLastError(); log_error("Could not initialize Windows Sockets 2.2: %s (%d)", get_errno_name(rc), rc); goto error_event; } if (event_init() < 0) { // FIXME: set service_exit_code goto error_event; } if (usb_init() < 0) { // FIXME: set service_exit_code goto error_usb; } // create notification pipe if (pipe_create(_notification_pipe) < 0) { // FIXME: set service_exit_code log_error("Could not create notification pipe: %s (%d)", get_errno_name(errno), errno); goto error_pipe; } if (event_add_source(_notification_pipe[0], EVENT_SOURCE_TYPE_GENERIC, EVENT_READ, forward_notifications, NULL) < 0) { // FIXME: set service_exit_code goto error_pipe_add; } // register device notification ZeroMemory(¬ification_filter, sizeof(notification_filter)); notification_filter.dbcc_size = sizeof(notification_filter); notification_filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; notification_filter.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE; if (_run_as_service) { notification_handle = RegisterDeviceNotification((HANDLE)service_get_status_handle(), ¬ification_filter, DEVICE_NOTIFY_SERVICE_HANDLE); } else { if (message_pump_start() < 0) { // FIXME: set service_exit_code goto error_pipe_add; } notification_handle = RegisterDeviceNotification(_message_pump_hwnd, ¬ification_filter, DEVICE_NOTIFY_WINDOW_HANDLE); } if (notification_handle == NULL) { // FIXME: set service_exit_code rc = ERRNO_WINAPI_OFFSET + GetLastError(); log_error("Could not register for device notification: %s (%d)", get_errno_name(rc), rc); goto error_notification; } if (network_init() < 0) { // FIXME: set service_exit_code goto error_network; } // running if (_run_as_service) { service_set_status(SERVICE_RUNNING, NO_ERROR); } if (event_run() < 0) { // FIXME: set service_exit_code goto error_run; } exit_code = EXIT_SUCCESS; error_run: network_exit(); error_network: UnregisterDeviceNotification(notification_handle); error_notification: if (!_run_as_service) { message_pump_stop(); } event_remove_source(_notification_pipe[0], EVENT_SOURCE_TYPE_GENERIC); error_pipe_add: pipe_destroy(_notification_pipe); error_pipe: usb_exit(); error_usb: event_exit(); error_event: log_info("Brick Daemon %s stopped", VERSION_STRING); error: log_exit(); config_exit(); if (_run_as_service) { // because the service process can be terminated at any time after // entering SERVICE_STOPPED state the mutex is closed beforehand, // even though this creates a tiny time window in which the service // is still running but the mutex is not held anymore if (mutex_handle != NULL) { CloseHandle(mutex_handle); } // service is now stopped service_set_status(SERVICE_STOPPED, service_exit_code); } else { if (_pause_before_exit) { printf("Press any key to exit...\n"); getch(); } if (mutex_handle != NULL) { CloseHandle(mutex_handle); } } return exit_code; }
// NOTE: this function needs to call RegisterServiceCtrlHandlerEx and // SetServiceStatus in all circumstances if brickd is running as service static int generic_main(bool log_to_file, bool debug, bool libusb_debug) { int exit_code = EXIT_FAILURE; const char *mutex_name = "Global\\Tinkerforge-Brick-Daemon-Single-Instance"; HANDLE mutex_handle = NULL; bool fatal_error = false; DWORD service_exit_code = NO_ERROR; int rc; char filename[1024]; int i; FILE *log_file = NULL; WSADATA wsa_data; DEV_BROADCAST_DEVICEINTERFACE notification_filter; HDEVNOTIFY notification_handle; mutex_handle = OpenMutex(SYNCHRONIZE, FALSE, mutex_name); if (mutex_handle == NULL) { rc = GetLastError(); if (rc == ERROR_ACCESS_DENIED) { rc = service_is_running(); if (rc < 0) { fatal_error = true; // FIXME: set service_exit_code goto error_mutex; } else if (rc) { fatal_error = true; service_exit_code = ERROR_SERVICE_ALREADY_RUNNING; log_error("Could not start as %s, another instance is already running as service", _run_as_service ? "service" : "console application"); goto error_mutex; } } if (rc != ERROR_FILE_NOT_FOUND) { fatal_error = true; // FIXME: set service_exit_code rc += ERRNO_WINAPI_OFFSET; log_error("Could not open single instance mutex: %s (%d)", get_errno_name(rc), rc); goto error_mutex; } } if (mutex_handle != NULL) { fatal_error = true; service_exit_code = ERROR_SERVICE_ALREADY_RUNNING; log_error("Could not start as %s, another instance is already running", _run_as_service ? "service" : "console application"); goto error_mutex; } mutex_handle = CreateMutex(NULL, FALSE, mutex_name); if (mutex_handle == NULL) { fatal_error = true; // FIXME: set service_exit_code rc = ERRNO_WINAPI_OFFSET + GetLastError(); log_error("Could not create single instance mutex: %s (%d)", get_errno_name(rc), rc); goto error_mutex; } if (log_to_file) { if (GetModuleFileName(NULL, filename, sizeof(filename)) == 0) { rc = ERRNO_WINAPI_OFFSET + GetLastError(); log_warn("Could not get module file name: %s (%d)", get_errno_name(rc), rc); } else { i = strlen(filename); if (i < 4) { log_warn("Module file name '%s' is too short", filename); } else { filename[i - 3] = '\0'; string_append(filename, "log", sizeof(filename)); log_file = fopen(filename, "a+"); if (log_file == NULL) { log_warn("Could not open log file '%s'", filename); } else { printf("Logging to '%s'\n", filename); log_set_file(log_file); } } } } else if (_run_as_service) { log_set_file(NULL); } if (!_run_as_service && !SetConsoleCtrlHandler(console_ctrl_handler, TRUE)) { rc = ERRNO_WINAPI_OFFSET + GetLastError(); log_warn("Could not set console control handler: %s (%d)", get_errno_name(rc), rc); } log_set_debug_override(debug); log_set_level(LOG_CATEGORY_EVENT, config_get_option("log_level.event")->value.log_level); log_set_level(LOG_CATEGORY_USB, config_get_option("log_level.usb")->value.log_level); log_set_level(LOG_CATEGORY_NETWORK, config_get_option("log_level.network")->value.log_level); log_set_level(LOG_CATEGORY_HOTPLUG, config_get_option("log_level.hotplug")->value.log_level); log_set_level(LOG_CATEGORY_HARDWARE, config_get_option("log_level.hardware")->value.log_level); log_set_level(LOG_CATEGORY_WEBSOCKET, config_get_option("log_level.websocket")->value.log_level); log_set_level(LOG_CATEGORY_OTHER, config_get_option("log_level.other")->value.log_level); if (config_has_error()) { log_error("Error(s) in config file '%s', run with --check-config option for details", _config_filename); fatal_error = true; goto error_config; } if (_run_as_service) { log_info("Brick Daemon %s started (as service)", VERSION_STRING); } else { log_info("Brick Daemon %s started", VERSION_STRING); } if (config_has_warning()) { log_warn("Warning(s) in config file '%s', run with --check-config option for details", _config_filename); } // initialize service status error_config: error_mutex: if (_run_as_service) { if (service_init(service_control_handler) < 0) { // FIXME: set service_exit_code goto error; } if (!fatal_error) { // service is starting service_set_status(SERVICE_START_PENDING, NO_ERROR); } } if (fatal_error) { goto error; } // initialize WinSock2 if (WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0) { // FIXME: set service_exit_code rc = ERRNO_WINAPI_OFFSET + WSAGetLastError(); log_error("Could not initialize Windows Sockets 2.2: %s (%d)", get_errno_name(rc), rc); goto error_event; } if (event_init() < 0) { // FIXME: set service_exit_code goto error_event; } if (hardware_init() < 0) { // FIXME: set service_exit_code goto error_hardware; } if (usb_init(libusb_debug) < 0) { // FIXME: set service_exit_code goto error_usb; } // create notification pipe if (pipe_create(&_notification_pipe) < 0) { // FIXME: set service_exit_code log_error("Could not create notification pipe: %s (%d)", get_errno_name(errno), errno); goto error_pipe; } if (event_add_source(_notification_pipe.read_end, EVENT_SOURCE_TYPE_GENERIC, EVENT_READ, forward_notifications, NULL) < 0) { // FIXME: set service_exit_code goto error_pipe_add; } // register device notification ZeroMemory(¬ification_filter, sizeof(notification_filter)); notification_filter.dbcc_size = sizeof(notification_filter); notification_filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; notification_filter.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE; if (_run_as_service) { notification_handle = RegisterDeviceNotification((HANDLE)service_get_status_handle(), ¬ification_filter, DEVICE_NOTIFY_SERVICE_HANDLE); } else { if (message_pump_start() < 0) { // FIXME: set service_exit_code goto error_pipe_add; } notification_handle = RegisterDeviceNotification(_message_pump_hwnd, ¬ification_filter, DEVICE_NOTIFY_WINDOW_HANDLE); } if (notification_handle == NULL) { // FIXME: set service_exit_code rc = ERRNO_WINAPI_OFFSET + GetLastError(); log_error("Could not register for device notification: %s (%d)", get_errno_name(rc), rc); goto error_notification; } if (network_init() < 0) { // FIXME: set service_exit_code goto error_network; } // running if (_run_as_service) { service_set_status(SERVICE_RUNNING, NO_ERROR); } if (event_run(network_cleanup_clients_and_zombies) < 0) { // FIXME: set service_exit_code goto error_run; } exit_code = EXIT_SUCCESS; error_run: network_exit(); error_network: UnregisterDeviceNotification(notification_handle); error_notification: if (!_run_as_service) { message_pump_stop(); } event_remove_source(_notification_pipe.read_end, EVENT_SOURCE_TYPE_GENERIC); error_pipe_add: pipe_destroy(&_notification_pipe); error_pipe: usb_exit(); error_usb: hardware_exit(); error_hardware: event_exit(); error_event: log_info("Brick Daemon %s stopped", VERSION_STRING); error: if (!_run_as_service) { // unregister the console handler before exiting the log. otherwise a // control event might be send to the control handler after the log // is not available anymore and the control handler tries to write a // log messages triggering a crash. this situation could easily be // created by clicking the close button of the command prompt window // while the getch call is waiting for the user to press a key. SetConsoleCtrlHandler(console_ctrl_handler, FALSE); } log_exit(); config_exit(); if (_run_as_service) { // because the service process can be terminated at any time after // entering SERVICE_STOPPED state the mutex is closed beforehand, // even though this creates a tiny time window in which the service // is still running but the mutex is not held anymore if (mutex_handle != NULL) { CloseHandle(mutex_handle); } // service is now stopped service_set_status(SERVICE_STOPPED, service_exit_code); } else { if (_pause_before_exit) { printf("Press any key to exit...\n"); getch(); } if (mutex_handle != NULL) { CloseHandle(mutex_handle); } } return exit_code; }
// // WinProcCallback // INT_PTR WINAPI WinProcCallback( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) // Routine Description: // Simple Windows callback for handling messages. // This is where all the work is done because the example // is using a window to process messages. This logic would be handled // differently if registering a service instead of a window. // Parameters: // hWnd - the window handle being registered for events. // message - the message being interpreted. // wParam and lParam - extended information provided to this // callback by the message sender. // For more information regarding these parameters and return value, // see the documentation for WNDCLASSEX and CreateWindowEx. { LRESULT lRet = 1; static HDEVNOTIFY hDeviceNotify; static HWND hEditWnd; static ULONGLONG msgCount = 0; switch (message) { case WM_CREATE: // // This is the actual registration., In this example, registration // should happen only once, at application startup when the window // is created. // // If you were using a service, you would put this in your main code // path as part of your service initialization. // if (!DoRegisterDeviceInterfaceToHwnd( WceusbshGUID, hWnd, &hDeviceNotify)) { // Terminate on failure. ErrorHandler(TEXT("DoRegisterDeviceInterfaceToHwnd")); ExitProcess(1); } // // Make the child window for output. // hEditWnd = CreateWindow(TEXT("EDIT"),// predefined class NULL, // no window title WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL, 0, 0, 0, 0, // set size in WM_SIZE message hWnd, // parent window (HMENU)1, // edit control ID (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), NULL); // pointer not needed if (hEditWnd == NULL) { // Terminate on failure. ErrorHandler(TEXT("CreateWindow: Edit Control")); ExitProcess(1); } // Add text to the window. SendMessage(hEditWnd, WM_SETTEXT, 0, (LPARAM)TEXT("Registered for USB device notification...\n")); break; case WM_SETFOCUS: SetFocus(hEditWnd); break; case WM_SIZE: // Make the edit control the size of the window's client area. MoveWindow(hEditWnd, 0, 0, // starting x- and y-coordinates LOWORD(lParam), // width of client area HIWORD(lParam), // height of client area TRUE); // repaint window break; case WM_DEVICECHANGE: { // // This is the actual message from the interface via Windows messaging. // This code includes some additional decoding for this particular device type // and some common validation checks. // // Note that not all devices utilize these optional parameters in the same // way. Refer to the extended information for your particular device type // specified by your GUID. // PDEV_BROADCAST_DEVICEINTERFACE b = (PDEV_BROADCAST_DEVICEINTERFACE)lParam; TCHAR strBuff[256]; // Output some messages to the window. switch (wParam) { case DBT_DEVICEARRIVAL: msgCount++; StringCchPrintf( strBuff, 256, TEXT("Message %d: DBT_DEVICEARRIVAL\n"), msgCount); break; case DBT_DEVICEREMOVECOMPLETE: msgCount++; StringCchPrintf( strBuff, 256, TEXT("Message %d: DBT_DEVICEREMOVECOMPLETE\n"), msgCount); break; case DBT_DEVNODES_CHANGED: msgCount++; StringCchPrintf( strBuff, 256, TEXT("Message %d: DBT_DEVNODES_CHANGED\n"), msgCount); break; default: msgCount++; StringCchPrintf( strBuff, 256, TEXT("Message %d: WM_DEVICECHANGE message received, value %d unhandled.\n"), msgCount, wParam); break; } OutputMessage(hEditWnd, wParam, (LPARAM)strBuff); } break; case WM_CLOSE: if (!UnregisterDeviceNotification(hDeviceNotify)) { ErrorHandler(TEXT("UnregisterDeviceNotification")); } DestroyWindow(hWnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: // Send all other messages on to the default windows handler. lRet = DefWindowProc(hWnd, message, wParam, lParam); break; } return lRet; }
BOOL CALLBACK dialog_proc_1(HWND dialog, UINT message, WPARAM wParam, LPARAM lParam) { static HDEVNOTIFY notification_handle_hub = NULL; static HDEVNOTIFY notification_handle_dev = NULL; DEV_BROADCAST_HDR *hdr = (DEV_BROADCAST_HDR *) lParam; DEV_BROADCAST_DEVICEINTERFACE dev_if; static device_context_t *device = NULL; HWND list = GetDlgItem(dialog, ID_LIST); LVITEM item; switch (message) { case WM_INITDIALOG: SendMessage(dialog,WM_SETICON,ICON_SMALL, (LPARAM)mIcon); SendMessage(dialog,WM_SETICON,ICON_BIG, (LPARAM)mIcon); device = (device_context_t *)lParam; if (device->user_allocated_wdi) { if (device->wdi) { free(device->wdi); device->wdi = NULL; } device->user_allocated_wdi = FALSE; } g_hwndTrackingTT = CreateTrackingToolTip(list, TEXT(" ")); #if defined(_WIN64) device_list_wndproc_orig = (WNDPROC)SetWindowLongPtr(list, GWLP_WNDPROC, (UINT_PTR)device_list_wndproc); #else device_list_wndproc_orig = (WNDPROC)SetWindowLongPtr(list, GWL_WNDPROC, (UINT_PTR)device_list_wndproc); #endif memset(device, 0, sizeof(*device)); SetWindowText(GetDlgItem(dialog, ID_LIST_HEADER_TEXT), list_header_text); device_list_init(list); device_list_refresh(list); dev_if.dbcc_size = sizeof(dev_if); dev_if.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; dev_if.dbcc_classguid = GUID_DEVINTERFACE_USB_HUB; notification_handle_hub = RegisterDeviceNotification(dialog, &dev_if, 0); dev_if.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE; notification_handle_dev = RegisterDeviceNotification(dialog, &dev_if, 0); return TRUE; case WM_DEVICECHANGE: switch (wParam) { case DBT_DEVICEREMOVECOMPLETE: if (hdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) device_list_refresh(list); break; case DBT_DEVICEARRIVAL: if (hdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) device_list_refresh(list); break; default: ; } return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case ID_BUTTON_NEXT: if (notification_handle_hub) UnregisterDeviceNotification(notification_handle_hub); if (notification_handle_dev) UnregisterDeviceNotification(notification_handle_dev); memset(&item, 0, sizeof(item)); item.mask = LVIF_TEXT | LVIF_PARAM; item.iItem = ListView_GetNextItem(list, -1, LVNI_SELECTED); memset(device, 0, sizeof(*device)); if (item.iItem >= 0) { if (ListView_GetItem(list, &item)) { if (item.lParam) { memcpy(device, (void *)item.lParam, sizeof(*device)); } } } if (!device->wdi) { device->user_allocated_wdi = TRUE; device->wdi = malloc(sizeof(struct wdi_device_info)); memset(device->wdi,0,sizeof(struct wdi_device_info)); device->wdi->vid = 0x12AB; device->wdi->pid = 0x12AB; } if (!device->manufacturer[0]) strcpy(device->manufacturer, "Insert manufacturer name"); if (!device->description[0]) strcpy(device->description, "Insert device description"); device_list_clean(list); EndDialog(dialog, ID_DIALOG_2); return TRUE; case ID_BUTTON_BACK: device_list_clean(list); if (notification_handle_hub) UnregisterDeviceNotification(notification_handle_hub); if (notification_handle_dev) UnregisterDeviceNotification(notification_handle_dev); EndDialog(dialog, ID_DIALOG_0); return TRUE ; case ID_BUTTON_CANCEL: case IDCANCEL: device_list_clean(list); if (notification_handle_hub) UnregisterDeviceNotification(notification_handle_hub); if (notification_handle_dev) UnregisterDeviceNotification(notification_handle_dev); EndDialog(dialog, 0); return TRUE ; } } return FALSE; }