コード例 #1
0
ファイル: USBDetect.cpp プロジェクト: tqtam/LUANVAN
//
// DoRegisterDeviceInterfaceToHwnd
//
BOOL DoRegisterDeviceInterfaceToHwnd(
	IN GUID InterfaceClassGuid,
	IN HWND hWnd,
	OUT HDEVNOTIFY *hDeviceNotify
	)
	// Routine Description:
	//     Registers an HWND for notification of changes in the device interfaces
	//     for the specified interface class GUID. 

	// Parameters:
	//     InterfaceClassGuid - The interface class GUID for the device 
	//         interfaces. 

	//     hWnd - Window handle to receive notifications.

	//     hDeviceNotify - Receives the device notification handle. On failure, 
	//         this value is NULL.

	// Return Value:
	//     If the function succeeds, the return value is TRUE.
	//     If the function fails, the return value is FALSE.

	// Note:
	//     RegisterDeviceNotification also allows a service handle be used,
	//     so a similar wrapper function to this one supporting that scenario
	//     could be made from this template.
{
	DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;

	ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
	NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
	NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
	NotificationFilter.dbcc_classguid = InterfaceClassGuid;

	*hDeviceNotify = RegisterDeviceNotification(
		hWnd,                       // events recipient
		&NotificationFilter,        // type of device
		DEVICE_NOTIFY_WINDOW_HANDLE // type of recipient handle
		);

	if (NULL == *hDeviceNotify)
	{
		ErrorHandler(TEXT("RegisterDeviceNotification"));
		return FALSE;
	}

	return TRUE;
}
コード例 #2
0
bool QNotifierListener::Start(GUID guid)
{
    DEV_BROADCAST_DEVICEINTERFACE notificationFilter;

    memset(&notificationFilter, 0, sizeof(DEV_BROADCAST_DEVICEINTERFACE));
    notificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
    notificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
    notificationFilter.dbcc_classguid = guid;

    HDEVNOTIFY devNotify =
            RegisterDeviceNotification((HANDLE)this->winId(),
                                       &notificationFilter,
                                       DEVICE_NOTIFY_WINDOW_HANDLE);

    return devNotify != NULL;
}
コード例 #3
0
ファイル: XnUSBWin32.cpp プロジェクト: 1170390/OpenNI2
//---------------------------------------------------------------------------
// Code
//---------------------------------------------------------------------------
XnStatus xnUSBPlatformSpecificInit()
{
	XnStatus nRetVal = XN_STATUS_OK;

	// give a unique class name (there might be multiple instances of this code in multiple DLLs)
	char className[MAX_PATH];
	sprintf_s(className, "xnUsbDeviceDetector%x", &g_xnUsbhModule);

	WNDCLASS wc;
	wc.style = 0;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = (HINSTANCE)g_xnUsbhModule;
	wc.hbrBackground = NULL;
	wc.lpszMenuName = NULL;
	wc.lpszClassName = className;
	wc.lpfnWndProc = DevDetectWndProc;
	wc.hIcon = NULL;
	wc.hCursor = NULL;

	g_xnClass = RegisterClass(&wc);
	if (g_xnClass)
	{
		HANDLE hWaitEv = CreateEvent(NULL,FALSE,FALSE,NULL);
		g_bUsbDevDetectShoudRun = TRUE;
		nRetVal = xnOSCreateThread(DevDetectThread, hWaitEv, &g_xnUsbhPnThread);
		XN_IS_STATUS_OK(nRetVal);

		WaitForSingleObject(hWaitEv,INFINITE);
		CloseHandle(hWaitEv);
	}
	else
	{
		return (XN_STATUS_USB_FAILED_TO_REGISTER_CALLBACK);
	}

	DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
	ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
	NotificationFilter.dbcc_size =  sizeof(DEV_BROADCAST_DEVICEINTERFACE);
	NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
	NotificationFilter.dbcc_classguid = GUID_CLASS_PSDRV_USB;
	RegisterDeviceNotification(g_xnUsbhDevDetectWnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);

	return (XN_STATUS_OK);
}
コード例 #4
0
ファイル: qextserialenumerator.cpp プロジェクト: Ariki/QGIS
    void QextSerialEnumerator::setUpNotificationWin( )
    {
        #ifdef QT_GUI_LIB
        if(notificationWidget)
            return;
        notificationWidget = new QextSerialRegistrationWidget(this);

        DEV_BROADCAST_DEVICEINTERFACE dbh;
        ZeroMemory(&dbh, sizeof(dbh));
        dbh.dbcc_size = sizeof(dbh);
        dbh.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
        CopyMemory(&dbh.dbcc_classguid, &GUID_DEVCLASS_PORTS, sizeof(GUID));
        if( RegisterDeviceNotification( notificationWidget->winId( ), &dbh, DEVICE_NOTIFY_WINDOW_HANDLE ) == NULL)
            qWarning() << "RegisterDeviceNotification failed:" << GetLastError();
        #else
        qWarning("QextSerialEnumerator: GUI not enabled - can't register for device notifications.");
        #endif // QT_GUI_LIB
    }
コード例 #5
0
nsresult
sbWinRegisterDeviceHandleNotification(HDEVNOTIFY* aDeviceNotification,
                                      HWND        aEventWindow,
                                      DEVINST     aDevInst,
                                      const GUID& aGUID)
{
  // Validate arguments.
  NS_ENSURE_ARG_POINTER(aDeviceNotification);

  // Function variables.
  nsresult rv;

  // Create a device file for notifications.
  sbAutoHANDLE deviceHandle;
  rv = sbWinCreateDeviceFile(deviceHandle.StartAssignment(),
                             aDevInst,
                             &aGUID,
                             0,
                             FILE_SHARE_READ | FILE_SHARE_WRITE,
                             NULL,
                             OPEN_EXISTING,
                             0,
                             NULL);
  NS_ENSURE_SUCCESS(rv, rv);

  // Register for device handle notifications.  The handle may be closed after
  // registration without affecting the registration.  Doing so avoids having
  // extra device file handles open.
  HDEVNOTIFY           deviceNotification;
  DEV_BROADCAST_HANDLE devBroadcast = {0};
  devBroadcast.dbch_size = sizeof(devBroadcast);
  devBroadcast.dbch_devicetype = DBT_DEVTYP_HANDLE;
  devBroadcast.dbch_handle = deviceHandle;
  deviceNotification = RegisterDeviceNotification(aEventWindow,
                                                  &devBroadcast,
                                                  0);
  NS_ENSURE_TRUE(deviceNotification, NS_ERROR_FAILURE);

  // Return results.
  *aDeviceNotification = deviceNotification;

  return NS_OK;
}
コード例 #6
0
// Implementation
bool register_device_notifications(GUID guid, HWND h_wnd,
		HDEVNOTIFY *ph_device_notify)
// Routine Description:
//     Registers an HWND for notification of changes in the device interfaces
//     for the specified interface class GUID.

// Parameters:
//     InterfaceClassGuid - The interface class GUID for the device
//         interfaces.

//     hWnd - Window handle to receive notifications.

//     hDeviceNotify - Receives the device notification handle. On failure,
//         this value is NULL.

// Return Value:
//     If the function succeeds, the return value is TRUE.
//     If the function fails, the return value is FALSE.

// Note:
//     RegisterDeviceNotification also allows a service handle be used,
//     so a similar wrapper function to this one supporting that scenario
//     could be made from this template.
{
	DEV_BROADCAST_DEVICEINTERFACE notification_filter;

	ZeroMemory( &notification_filter, sizeof(notification_filter) );
	notification_filter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
	notification_filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
	notification_filter.dbcc_classguid = guid;

	*ph_device_notify = RegisterDeviceNotification(h_wnd, // events recipient
			&notification_filter, // type of device
			DEVICE_NOTIFY_WINDOW_HANDLE // type of recipient handle
			);

	if (NULL == *ph_device_notify)
	{
		return false;
	}

	return true;
}
コード例 #7
0
void pjrc_rawhid::setUpNotifications( )
{
#ifdef QT_GUI_LIB
    if(notificationWidget)
        return;
    notificationWidget = new USBRegistrationWidget(this);

    DEV_BROADCAST_DEVICEINTERFACE dbh;
    ZeroMemory(&dbh, sizeof(dbh));
    dbh.dbcc_size = sizeof(dbh);
    dbh.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
    CopyMemory(&dbh.dbcc_classguid, &GUID_DEVCLASS_PORTS, sizeof(GUID));
    if( RegisterDeviceNotification( notificationWidget->winId( ), &dbh, DEVICE_NOTIFY_WINDOW_HANDLE ) == NULL)
        qWarning() << "RegisterDeviceNotification failed:" << GetLastError();
    // setting up notifications doesn't tell us about devices already connected
    // so get those manually
#else
    qWarning("GUI not enabled - can't register for device notifications.");
#endif // QT_GUI_LIB
}
コード例 #8
0
ファイル: UsbSerial.cpp プロジェクト: sanjog47/makecontroller
 // make sure to do this only once the device has been opened,
 // since it relies on the deviceHandle to register for the call.
bool UsbSerial::DoRegisterForNotification( )
{
	DEV_BROADCAST_HANDLE NotificationFilter;
	
	ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
	NotificationFilter.dbch_size = sizeof( DEV_BROADCAST_HANDLE );
	NotificationFilter.dbch_devicetype = DBT_DEVTYP_HANDLE;
	NotificationFilter.dbch_handle = deviceHandle;  // class variable
	HWND winId = mainWindow->winId( );

    notificationHandle = RegisterDeviceNotification( winId, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE );

    if(!notificationHandle) 
    {
        qDebug( "RegisterDeviceNotification failed: %ld\n", GetLastError());
        return false;
    }
    qDebug( "RegisterDeviceNotification success\n" );
    return true;
}
コード例 #9
0
ファイル: notifier_win.cpp プロジェクト: radiomanV/TL866
Notifier::Notifier(QWidget *parent) :
    QWidget(parent)
{
    //We use a hidden widget class because we need the winId (hwnd) for Windows implementation.
    this->hide();
    const GUID MINIPRO_GUID={0x85980D83,0x32B9,0x4BA1,{0x8F,0xDF,0x12,0xA7,0x11,0xB9,0x9C,0xA2}};
    DEV_BROADCAST_DEVICEINTERFACE deviceInterface;
    ZeroMemory(&deviceInterface, sizeof(deviceInterface));
    deviceInterface.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
    deviceInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
    deviceInterface.dbcc_classguid  = MINIPRO_GUID;
    HDEVNOTIFY m_notify_handle = RegisterDeviceNotification(reinterpret_cast<HANDLE>(this->winId()),&deviceInterface, DEVICE_NOTIFY_WINDOW_HANDLE);
    if(m_notify_handle==nullptr)
    {
        qDebug() << "Failed to register device notification!";
        return;
    }

    qDebug() << "Register device notification O.K.";
}
コード例 #10
0
FlashTool::FlashTool(QWidget *parent)
 : QWidget(parent)
 , ui(new Ui::FlashTool)
{
    ui->setupUi(this);

    updatePorts();

    // Listen to device events
    DEV_BROADCAST_DEVICEINTERFACE devInt;
    ZeroMemory(&devInt, sizeof(devInt));
    devInt.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
    devInt.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
    devInt.dbcc_classguid = GUID_DEVINTERFACE_COMPORT;

    HANDLE blub;
    blub = RegisterDeviceNotification(winId(), &devInt, DEVICE_NOTIFY_WINDOW_HANDLE);


    connect(ui->bootFlashButton, SIGNAL(clicked()), SLOT(flashBootloader()));
    connect(ui->flashButton, SIGNAL(clicked()), SLOT(flashFirmware()));
}
コード例 #11
0
void QextSerialEnumerator::setUpNotifications( )
{
    #ifdef QT_GUI_LIB
    if(notificationWidget)
        return;
    notificationWidget = new QextSerialRegistrationWidget(this);

    DEV_BROADCAST_DEVICEINTERFACE dbh;
    ZeroMemory(&dbh, sizeof(dbh));
    dbh.dbcc_size = sizeof(dbh);
    dbh.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
    //CopyMemory(&dbh.dbcc_classguid, &GUID_DEVCLASS_PORTS, sizeof(GUID));
    CopyMemory(&dbh.dbcc_classguid, &GUID_DEVCLASS_USBRAW, sizeof(GUID));
    if( RegisterDeviceNotification( notificationWidget->winId( ), &dbh, DEVICE_NOTIFY_WINDOW_HANDLE ) == NULL)
        qWarning() << "RegisterDeviceNotification failed:" << GetLastError();
    // setting up notifications doesn't tell us about devices already connected
    // so get those manually
    foreach( QextPortInfo port, getPorts() )
      emit deviceDiscovered( port );
    #else
    qWarning("QextSerialEnumerator: GUI not enabled - can't register for device notifications.");
    #endif // QT_GUI_LIB
}
コード例 #12
0
/*------------------------------------------------------------------------------*/
BOOL AkindDI::Init( HWND hWnd, BOOL BackGround )
{
	HRESULT hRes;
	HINSTANCE hInstance = GetModuleHandle( NULL );

	m_hWnd = hWnd;
	m_JoyNum = 0;
	m_BackGround = BackGround;

	ZeroMemory( m_KeyBuff, sizeof(m_KeyBuff) );
	ZeroMemory( m_JoyGUID, sizeof(m_JoyGUID) );
	ZeroMemory( m_JoyData, sizeof(m_JoyData) );
	for ( int i=0; i<JOY_MAX; i++ ){ m_JoyReady[i] = FALSE; }

	hRes = DirectInput8Create( hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (LPVOID*)&m_pDInput, NULL );
	if ( FAILED( hRes ) ){ Error( 0, hRes ); return( FALSE ); }
	hRes = m_pDInput->CreateDevice( GUID_SysKeyboard, &m_pDInputKey, NULL );
	if ( FAILED( hRes ) ){ Error( 1, hRes ); return( FALSE ); }
	hRes = m_pDInputKey->SetDataFormat( &c_dfDIKeyboard );
	if ( FAILED( hRes ) ){ Error( 2, hRes ); return( FALSE ); }
	if ( m_BackGround ){
		hRes = m_pDInputKey->SetCooperativeLevel( hWnd, DISCL_BACKGROUND|DISCL_NONEXCLUSIVE );
	} else {
		hRes = m_pDInputKey->SetCooperativeLevel( hWnd, DISCL_FOREGROUND|DISCL_NONEXCLUSIVE );
	}
	if ( FAILED( hRes ) ){ Error( 3, hRes ); return( FALSE ); }

	JoyAdd();

	DEV_BROADCAST_DEVICEINTERFACE filter;
	filter.dbcc_size       = sizeof(filter);
	filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
	filter.dbcc_classguid  = GUID_CLASS_INPUT;
	m_hJoyDeviceNotify = RegisterDeviceNotification( hWnd, &filter, DEVICE_NOTIFY_WINDOW_HANDLE );

	return( TRUE );
}
コード例 #13
0
ファイル: XnUSBWin32.cpp プロジェクト: jspricke/debian-openni
//---------------------------------------------------------------------------
// Code
//---------------------------------------------------------------------------
XnStatus xnUSBPlatformSpecificInit()
{
	WNDCLASS wc;
	wc.style = 0;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = (HINSTANCE)g_xnUsbhModule;
	wc.hbrBackground = NULL;
	wc.lpszMenuName = NULL;
	wc.lpszClassName = "xnUsbDeviceDetector";
	wc.lpfnWndProc = DevDetectWndProc;
	wc.hIcon = NULL;
	wc.hCursor = NULL;

	BOOL ret = RegisterClass(&wc);
	if(ret)
	{
		HANDLE hWaitEv = CreateEvent(NULL,FALSE,FALSE,NULL);
		g_xnUsbhPnThread = (HANDLE)_beginthread(DevDetectThread,0,(PVOID)hWaitEv);
		WaitForSingleObject(hWaitEv,INFINITE);
		CloseHandle(hWaitEv);
	}
	else
	{
		return (XN_STATUS_USB_FAILED_TO_REGISTER_CALLBACK);
	}

	DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
	ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
	NotificationFilter.dbcc_size =  sizeof(DEV_BROADCAST_DEVICEINTERFACE);
	NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
	NotificationFilter.dbcc_classguid = GUID_CLASS_PSDRV_USB;
	RegisterDeviceNotification(g_xnUsbhDevDetectWnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);

	return (XN_STATUS_OK);
}
コード例 #14
0
BOOL CInterfacePlugInWnd::RegisterNotification()
{
	HDEVNOTIFY hDevNotify;
	DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
	BOOL oResult = TRUE;

	//Init NotificationFilter
	ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
    NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
    NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;

	//Register all Device Class Guids
	for(int i=0; i<sizeof(GUID_DEVINTERFACE_LIST)/sizeof(GUID); i++) 
	{
		NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_LIST[i];
		hDevNotify = RegisterDeviceNotification(this->GetSafeHwnd(),&NotificationFilter,DEVICE_NOTIFY_WINDOW_HANDLE);
		if(!hDevNotify )
		{
			oResult = FALSE;
		}
	}

	return oResult;
}
コード例 #15
0
void CDirectoryWatcher::WorkerThread()
{
	DWORD numBytes;
	CDirWatchInfo * pdi = NULL;
	LPOVERLAPPED lpOverlapped;
	WCHAR buf[READ_DIR_CHANGE_BUFFER_SIZE] = {0};
	WCHAR * pFound = NULL;
	while (m_bRunning)
	{
		CleanupWatchInfo();
		if (watchedPaths.GetCount())
		{
			// Any incoming notifications?

			pdi = NULL;
			numBytes = 0;
			InterlockedExchange(&m_bCleaned, FALSE);
			if ((!m_hCompPort)
				|| !GetQueuedCompletionStatus(m_hCompPort,
											  &numBytes,
											  (PULONG_PTR) &pdi,
											  &lpOverlapped,
											  600000 /*10 minutes*/))
			{
				// No. Still trying?

				if (!m_bRunning)
					return;

				ATLTRACE(_T(": restarting watcher\n"));
				m_hCompPort.CloseHandle();

				// We must sync the whole section because other threads may
				// receive "AddPath" calls that will delete the completion
				// port *while* we are adding references to it .

				AutoLocker lock(m_critSec);

				// Clear the list of watched objects and recreate that list.
				// This will also delete the old completion port

				ClearInfoMap();
				CleanupWatchInfo();

				for (int i=0; i<watchedPaths.GetCount(); ++i)
				{
					CTGitPath watchedPath = watchedPaths[i];

					CAutoFile hDir = CreateFile(watchedPath.GetWinPath(),
											FILE_LIST_DIRECTORY,
											FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
											NULL, //security attributes
											OPEN_EXISTING,
											FILE_FLAG_BACKUP_SEMANTICS | //required privileges: SE_BACKUP_NAME and SE_RESTORE_NAME.
											FILE_FLAG_OVERLAPPED,
											NULL);
					if (!hDir)
					{
						// this could happen if a watched folder has been removed/renamed
						ATLTRACE(_T("CDirectoryWatcher: CreateFile failed. Can't watch directory %s\n"), watchedPaths[i].GetWinPath());
						watchedPaths.RemovePath(watchedPath);
						break;
					}

					DEV_BROADCAST_HANDLE NotificationFilter;
					SecureZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
					NotificationFilter.dbch_size = sizeof(DEV_BROADCAST_HANDLE);
					NotificationFilter.dbch_devicetype = DBT_DEVTYP_HANDLE;
					NotificationFilter.dbch_handle = hDir;
					// RegisterDeviceNotification sends a message to the UI thread:
					// make sure we *can* send it and that the UI thread isn't waiting on a lock
					int numPaths = watchedPaths.GetCount();
					size_t numWatch = watchInfoMap.size();
					lock.Unlock();
					NotificationFilter.dbch_hdevnotify = RegisterDeviceNotification(hWnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
					lock.Lock();
					// since we released the lock to prevent a deadlock with the UI thread,
					// it could happen that new paths were added to watch, or another thread
					// could have cleared our info map.
					// if that happened, we have to restart watching all paths again.
					if ((numPaths != watchedPaths.GetCount()) || (numWatch != watchInfoMap.size()))
					{
						ClearInfoMap();
						CleanupWatchInfo();
						Sleep(200);
						break;
					}

					CDirWatchInfo * pDirInfo = new CDirWatchInfo(hDir, watchedPath);
					hDir.Detach();  // the new CDirWatchInfo object owns the handle now
					pDirInfo->m_hDevNotify = NotificationFilter.dbch_hdevnotify;


					HANDLE port = CreateIoCompletionPort(pDirInfo->m_hDir, m_hCompPort, (ULONG_PTR)pDirInfo, 0);
					if (port == NULL)
					{
						ATLTRACE(_T("CDirectoryWatcher: CreateIoCompletionPort failed. Can't watch directory %s\n"), watchedPath.GetWinPath());

						// we must close the directory handle to allow ClearInfoMap()
						// to close the completion port properly
						pDirInfo->CloseDirectoryHandle();

						ClearInfoMap();
						CleanupWatchInfo();
						delete pDirInfo;
						pDirInfo = NULL;

						watchedPaths.RemovePath(watchedPath);
						break;
					}
					m_hCompPort = port;

					if (!ReadDirectoryChangesW(pDirInfo->m_hDir,
												pDirInfo->m_Buffer,
												READ_DIR_CHANGE_BUFFER_SIZE,
												TRUE,
												FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE,
												&numBytes,// not used
												&pDirInfo->m_Overlapped,
												NULL))  //no completion routine!
					{
						ATLTRACE(_T("CDirectoryWatcher: ReadDirectoryChangesW failed. Can't watch directory %s\n"), watchedPath.GetWinPath());

						// we must close the directory handle to allow ClearInfoMap()
						// to close the completion port properly
						pDirInfo->CloseDirectoryHandle();

						ClearInfoMap();
						CleanupWatchInfo();
						delete pDirInfo;
						pDirInfo = NULL;
						watchedPaths.RemovePath(watchedPath);
						break;
					}

					ATLTRACE(_T("watching path %s\n"), pDirInfo->m_DirName.GetWinPath());
					watchInfoMap[pDirInfo->m_hDir] = pDirInfo;
				}
			}
			else
			{
				if (!m_bRunning)
					return;
				if (watchInfoMap.empty())
					continue;

				// NOTE: the longer this code takes to execute until ReadDirectoryChangesW
				// is called again, the higher the chance that we miss some
				// changes in the file system!
				if (pdi)
				{
					BOOL bRet = false;
					std::list<CTGitPath> notifyPaths;
					{
						AutoLocker lock(m_critSec);
						// in case the CDirectoryWatcher objects have been cleaned,
						// the m_bCleaned variable will be set to true here. If the
						// objects haven't been cleared, we can access them here.
						if (InterlockedExchange(&m_bCleaned, FALSE))
							continue;
						if (   (!pdi->m_hDir) || watchInfoMap.empty()
							|| (watchInfoMap.find(pdi->m_hDir) == watchInfoMap.end()))
						{
							continue;
						}
						PFILE_NOTIFY_INFORMATION pnotify = (PFILE_NOTIFY_INFORMATION)pdi->m_Buffer;
						DWORD nOffset = 0;

						do
						{
							pnotify = (PFILE_NOTIFY_INFORMATION)((LPBYTE)pnotify + nOffset);

							if ((ULONG_PTR)pnotify - (ULONG_PTR)pdi->m_Buffer > READ_DIR_CHANGE_BUFFER_SIZE)
								break;

							nOffset = pnotify->NextEntryOffset;

							if (pnotify->FileNameLength >= (READ_DIR_CHANGE_BUFFER_SIZE*sizeof(TCHAR)))
								continue;

							SecureZeroMemory(buf, READ_DIR_CHANGE_BUFFER_SIZE*sizeof(TCHAR));
							_tcsncpy_s(buf, pdi->m_DirPath, _countof(buf) - 1);
							errno_t err = _tcsncat_s(buf + pdi->m_DirPath.GetLength(), READ_DIR_CHANGE_BUFFER_SIZE-pdi->m_DirPath.GetLength(), pnotify->FileName, min(READ_DIR_CHANGE_BUFFER_SIZE-pdi->m_DirPath.GetLength(), pnotify->FileNameLength/sizeof(TCHAR)));
							if (err == STRUNCATE)
							{
								continue;
							}
							buf[(pnotify->FileNameLength/sizeof(TCHAR))+pdi->m_DirPath.GetLength()] = 0;

							if (m_FolderCrawler)
							{
								if ((pFound = wcsstr(buf, L"\\tmp")) != NULL)
								{
									pFound += 4;
									if (((*pFound)=='\\')||((*pFound)=='\0'))
									{
										continue;
									}
								}
								if ((pFound = wcsstr(buf, L":\\RECYCLER\\")) != NULL)
								{
									if ((pFound-buf) < 5)
									{
										// a notification for the recycle bin - ignore it
										continue;
									}
								}
								if ((pFound = wcsstr(buf, L":\\$Recycle.Bin\\")) != NULL)
								{
									if ((pFound-buf) < 5)
									{
										// a notification for the recycle bin - ignore it
										continue;
									}
								}
								if (wcsstr(buf, L".tmp") != NULL)
								{
									// assume files with a .tmp extension are not versioned and interesting,
									// so ignore them.
									continue;
								}

								CTGitPath path;
								bool isIndex = false;
								if ((pFound = wcsstr(buf, L".git")) != NULL)
								{
									// omit repository data change except .git/index.lock- or .git/HEAD.lock-files
									if ((ULONG_PTR)pnotify - (ULONG_PTR)pdi->m_Buffer > READ_DIR_CHANGE_BUFFER_SIZE)
										break;

									path = g_AdminDirMap.GetWorkingCopy(CTGitPath(buf).GetContainingDirectory().GetWinPathString());

									if ((wcsstr(pFound, L"index.lock") != NULL || wcsstr(pFound, L"HEAD.lock") != NULL) && pnotify->Action == FILE_ACTION_ADDED)
									{
										CGitStatusCache::Instance().BlockPath(path);
										continue;
									}
									else if (((wcsstr(pFound, L"index.lock") != NULL || wcsstr(pFound, L"HEAD.lock") != NULL) && pnotify->Action == FILE_ACTION_REMOVED) || (((wcsstr(pFound, L"index") != NULL && wcsstr(pFound, L"index.lock") == NULL) || (wcsstr(pFound, L"HEAD") != NULL && wcsstr(pFound, L"HEAD.lock") != NULL)) && pnotify->Action == FILE_ACTION_MODIFIED) || ((wcsstr(pFound, L"index.lock") == NULL || wcsstr(pFound, L"HEAD.lock") != NULL) && pnotify->Action == FILE_ACTION_RENAMED_NEW_NAME))
									{
										isIndex = true;
										CGitStatusCache::Instance().BlockPath(path, 1);
									}
									else
									{
										continue;
									}
								}
								else
									path.SetFromUnknown(buf);

								if(!path.HasAdminDir() && !isIndex)
									continue;

								ATLTRACE(_T("change notification: %s\n"), buf);
								notifyPaths.push_back(path);
							}
						} while ((nOffset > 0)&&(nOffset < READ_DIR_CHANGE_BUFFER_SIZE));

						// setup next notification cycle
						SecureZeroMemory (pdi->m_Buffer, sizeof(pdi->m_Buffer));
						SecureZeroMemory (&pdi->m_Overlapped, sizeof(OVERLAPPED));
						bRet = ReadDirectoryChangesW(pdi->m_hDir,
							pdi->m_Buffer,
							READ_DIR_CHANGE_BUFFER_SIZE,
							TRUE,
							FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE,
							&numBytes,// not used
							&pdi->m_Overlapped,
							NULL); //no completion routine!
					}
					if (!notifyPaths.empty())
					{
						for (std::list<CTGitPath>::const_iterator nit = notifyPaths.begin(); nit != notifyPaths.end(); ++nit)
						{
							m_FolderCrawler->AddPathForUpdate(*nit);
						}
					}

					// any clean-up to do?

					CleanupWatchInfo();

					if (!bRet)
					{
						// Since the call to ReadDirectoryChangesW failed, just
						// wait a while. We don't want to have this thread
						// running using 100% CPU if something goes completely
						// wrong.
						Sleep(200);
					}
				}
			}
		}// if (watchedPaths.GetCount())
		else
			Sleep(200);
	}// while (m_bRunning)
}
コード例 #16
0
ファイル: testlibusb_win.c プロジェクト: mcuee/libusb-win32
int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prev_instance,
                     LPSTR cmd_line, int cmd_show)
{
  MSG msg;
  WNDCLASSEX win_class;
  DEV_BROADCAST_DEVICEINTERFACE dev_if;

  LoadLibrary("comctl32.dll");

  win_class.cbSize = sizeof(WNDCLASSEX); 
  
  win_class.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS ;
  win_class.lpfnWndProc = win_proc;
  win_class.cbClsExtra = 0;
  win_class.cbWndExtra = 0;
  win_class.hInstance = instance;
  win_class.hIcon = NULL;
  win_class.hCursor = LoadCursor(NULL, IDC_ARROW);
  win_class.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
  win_class.lpszMenuName = NULL;
  win_class.lpszClassName = LIBUSB_WINDOW_CLASS;
  win_class.hIconSm = NULL;

  RegisterClassEx(&win_class);

  main_win = CreateWindowEx(WS_EX_APPWINDOW| WS_EX_CONTROLPARENT,
                            LIBUSB_WINDOW_CLASS, 
                            "TestLibUsb - Windows Version", 
                            WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN 
                            | WS_DLGFRAME,
                            CW_USEDEFAULT, 0, 500, 500, NULL, NULL, 
                            instance, NULL);
  if(!main_win) 
    {
      return FALSE;
    }


  exit_button = CreateWindow("BUTTON", "Exit",
                             WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
                             10, 10, 
                             LIBUSB_BUTTON_WIDTH, LIBUSB_BUTTON_HEIGHT, 
                             main_win, (HMENU) ID_EXIT, instance, NULL);

  refresh_button = CreateWindow("BUTTON", "Refresh",
                                WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
                                10, 100, 
                                LIBUSB_BUTTON_WIDTH, LIBUSB_BUTTON_HEIGHT, 
                                main_win, (HMENU) ID_REFRESH, instance, 
                                NULL);

  edit_box = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL,
                            WS_CHILD | WS_VISIBLE | WS_VSCROLL | 
                            ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL 
                            | ES_AUTOHSCROLL | ES_READONLY, 
                            CW_USEDEFAULT, CW_USEDEFAULT, 
                            CW_USEDEFAULT, CW_USEDEFAULT,
                            main_win, (HMENU) ID_EDIT, instance, NULL); 

  SendMessage(edit_box, WM_SETFONT, (WPARAM) CreateFont(13, 8, 0, 0,
                                                        400, 0, 0, 0,
                                                        0, 1, 2, 1,
                                                        49, "Courier"), 0);

  ShowWindow(main_win, cmd_show);
  UpdateWindow(main_win);
  BringWindowToTop(main_win);

  usb_set_debug(4);
  usb_init();
  usb_find_busses();

  on_refresh();

  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(main_win, &dev_if, 0);

  dev_if.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;

  notification_handle_dev = RegisterDeviceNotification(main_win, &dev_if, 0);

  while(GetMessage(&msg, NULL, 0, 0) ) 
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }

  DestroyWindow(main_win);
  UnregisterClass(LIBUSB_WINDOW_CLASS, instance);

  return 0;
}
コード例 #17
0
void CDirectoryWatcher::WorkerThread()
{
	DWORD numBytes;
	CDirWatchInfo * pdi = NULL;
	LPOVERLAPPED lpOverlapped;
	WCHAR buf[READ_DIR_CHANGE_BUFFER_SIZE] = {0};
	WCHAR * pFound = NULL;
	CTGitPath path;

	while (m_bRunning)
	{
		if (watchedPaths.GetCount())
		{
			if (!GetQueuedCompletionStatus(m_hCompPort,
											&numBytes,
											(PULONG_PTR) &pdi,
											&lpOverlapped,
											INFINITE))
			{
				// Error retrieving changes
				// Clear the list of watched objects and recreate that list
				if (!m_bRunning)
					return;
				{
					AutoLocker lock(m_critSec);
					ClearInfoMap();
				}
				DWORD lasterr = GetLastError();
				if ((m_hCompPort != INVALID_HANDLE_VALUE)&&(lasterr!=ERROR_SUCCESS)&&(lasterr!=ERROR_INVALID_HANDLE))
				{
					CloseHandle(m_hCompPort);
					m_hCompPort = INVALID_HANDLE_VALUE;
				}
				// Since we pass m_hCompPort to CreateIoCompletionPort, we
				// have to set this to NULL to have that API create a new
				// handle.
				m_hCompPort = NULL;
				for (int i=0; i<watchedPaths.GetCount(); ++i)
				{
					CTGitPath watchedPath = watchedPaths[i];

					HANDLE hDir = CreateFile(watchedPath.GetWinPath(),
											FILE_LIST_DIRECTORY,
											FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
											NULL, //security attributes
											OPEN_EXISTING,
											FILE_FLAG_BACKUP_SEMANTICS | //required privileges: SE_BACKUP_NAME and SE_RESTORE_NAME.
											FILE_FLAG_OVERLAPPED,
											NULL);
					if (hDir == INVALID_HANDLE_VALUE)
					{
						// this could happen if a watched folder has been removed/renamed
						ATLTRACE(_T("CDirectoryWatcher: CreateFile failed. Can't watch directory %s\n"), watchedPaths[i].GetWinPath());
						CloseHandle(m_hCompPort);
						m_hCompPort = INVALID_HANDLE_VALUE;
						AutoLocker lock(m_critSec);
						watchedPaths.RemovePath(watchedPath);
						i--; if (i<0) i=0;
						break;
					}

					DEV_BROADCAST_HANDLE NotificationFilter;
					SecureZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
					NotificationFilter.dbch_size = sizeof(DEV_BROADCAST_HANDLE);
					NotificationFilter.dbch_devicetype = DBT_DEVTYP_HANDLE;
					NotificationFilter.dbch_handle = hDir;
					NotificationFilter.dbch_hdevnotify = RegisterDeviceNotification(hWnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);

					CDirWatchInfo * pDirInfo = new CDirWatchInfo(hDir, watchedPath);
					pDirInfo->m_hDevNotify = NotificationFilter.dbch_hdevnotify;
					m_hCompPort = CreateIoCompletionPort(hDir, m_hCompPort, (ULONG_PTR)pDirInfo, 0);
					if (m_hCompPort == NULL)
					{
						ATLTRACE(_T("CDirectoryWatcher: CreateIoCompletionPort failed. Can't watch directory %s\n"), watchedPath.GetWinPath());
						AutoLocker lock(m_critSec);
						ClearInfoMap();
						delete pDirInfo;
						pDirInfo = NULL;
						watchedPaths.RemovePath(watchedPath);
						i--; if (i<0) i=0;
						break;
					}
					if (!ReadDirectoryChangesW(pDirInfo->m_hDir,
												pDirInfo->m_Buffer,
												READ_DIR_CHANGE_BUFFER_SIZE,
												TRUE,
												FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE,
												&numBytes,// not used
												&pDirInfo->m_Overlapped,
												NULL))	//no completion routine!
					{
						ATLTRACE(_T("CDirectoryWatcher: ReadDirectoryChangesW failed. Can't watch directory %s\n"), watchedPath.GetWinPath());
						AutoLocker lock(m_critSec);
						ClearInfoMap();
						delete pDirInfo;
						pDirInfo = NULL;
						watchedPaths.RemovePath(watchedPath);
						i--; if (i<0) i=0;
						break;
					}
					AutoLocker lock(m_critSec);
					watchInfoMap[pDirInfo->m_hDir] = pDirInfo;
					ATLTRACE(_T("watching path %s\n"), pDirInfo->m_DirName.GetWinPath());
				}
			}
			else
			{
				if (!m_bRunning)
					return;
				// NOTE: the longer this code takes to execute until ReadDirectoryChangesW
				// is called again, the higher the chance that we miss some
				// changes in the file system!
				if (pdi)
				{
					if (numBytes == 0)
					{
						goto continuewatching;
					}
					PFILE_NOTIFY_INFORMATION pnotify = (PFILE_NOTIFY_INFORMATION)pdi->m_Buffer;
					if ((ULONG_PTR)pnotify - (ULONG_PTR)pdi->m_Buffer > READ_DIR_CHANGE_BUFFER_SIZE)
						goto continuewatching;
					DWORD nOffset = pnotify->NextEntryOffset;

					do
					{
						nOffset = pnotify->NextEntryOffset;
						if (pnotify->FileNameLength >= (READ_DIR_CHANGE_BUFFER_SIZE*sizeof(TCHAR)))
							continue;
						SecureZeroMemory(buf, READ_DIR_CHANGE_BUFFER_SIZE*sizeof(TCHAR));
						_tcsncpy_s(buf, READ_DIR_CHANGE_BUFFER_SIZE, pdi->m_DirPath, READ_DIR_CHANGE_BUFFER_SIZE);
						errno_t err = _tcsncat_s(buf+pdi->m_DirPath.GetLength(), READ_DIR_CHANGE_BUFFER_SIZE-pdi->m_DirPath.GetLength(), pnotify->FileName, _TRUNCATE);
						if (err == STRUNCATE)
						{
							pnotify = (PFILE_NOTIFY_INFORMATION)((LPBYTE)pnotify + nOffset);
							continue;
						}
						buf[(pnotify->FileNameLength/sizeof(TCHAR))+pdi->m_DirPath.GetLength()] = 0;
						pnotify = (PFILE_NOTIFY_INFORMATION)((LPBYTE)pnotify + nOffset);
						if (m_FolderCrawler)
						{
							if ((pFound = wcsstr(buf, L"\\tmp"))!=NULL)
							{
								pFound += 4;
								if (((*pFound)=='\\')||((*pFound)=='\0'))
								{
									if ((ULONG_PTR)pnotify - (ULONG_PTR)pdi->m_Buffer > READ_DIR_CHANGE_BUFFER_SIZE)
										break;
									continue;
								}
							}
							if ((pFound = wcsstr(buf, L":\\RECYCLER\\"))!=NULL)
							{
								if ((pFound-buf) < 5)
								{
									// a notification for the recycle bin - ignore it
									if ((ULONG_PTR)pnotify - (ULONG_PTR)pdi->m_Buffer > READ_DIR_CHANGE_BUFFER_SIZE)
										break;
									continue;
								}
							}
							if ((pFound = wcsstr(buf, L":\\$Recycle.Bin\\"))!=NULL)
							{
								if ((pFound-buf) < 5)
								{
									// a notification for the recycle bin - ignore it
									if ((ULONG_PTR)pnotify - (ULONG_PTR)pdi->m_Buffer > READ_DIR_CHANGE_BUFFER_SIZE)
										break;
									continue;
								}
							}
							if ((pFound = wcsstr(buf, L".tmp"))!=NULL)
							{
								// assume files with a .tmp extension are not versioned and interesting,
								// so ignore them.
								if ((ULONG_PTR)pnotify - (ULONG_PTR)pdi->m_Buffer > READ_DIR_CHANGE_BUFFER_SIZE)
									break;
								continue;
							}
							bool isIndex = false;
							if ((pFound = wcsstr(buf, L".git"))!=NULL)
							{
								// omit repository data change except .git/index.lock- or .git/HEAD.lock-files
								if ((ULONG_PTR)pnotify - (ULONG_PTR)pdi->m_Buffer > READ_DIR_CHANGE_BUFFER_SIZE)
									break;

								if ((wcsstr(pFound, L"index.lock") != NULL && wcsstr(pFound, L"HEAD.lock") != NULL) && pnotify->Action == FILE_ACTION_ADDED)
								{
									m_FolderCrawler->BlockPath(CTGitPath(buf).GetContainingDirectory().GetContainingDirectory()); // optimize here, and use general BlockPath with priorities
									continue;
								}
								else if ((wcsstr(pFound, L"index.lock") != NULL && wcsstr(pFound, L"HEAD.lock") != NULL) && pnotify->Action == FILE_ACTION_REMOVED)
								{
									isIndex = true;
									m_FolderCrawler->BlockPath(CTGitPath(buf).GetContainingDirectory().GetContainingDirectory(), 1);
								}
								else
								{
									continue;
								}
							}

							path.SetFromWin(buf);
							if(!path.HasAdminDir() && !isIndex)
								continue;

							ATLTRACE(_T("change notification: %s\n"), buf);
							m_FolderCrawler->AddPathForUpdate(CTGitPath(buf));
						}
						if ((ULONG_PTR)pnotify - (ULONG_PTR)pdi->m_Buffer > READ_DIR_CHANGE_BUFFER_SIZE)
							break;
					} while (nOffset);
continuewatching:
					SecureZeroMemory(pdi->m_Buffer, sizeof(pdi->m_Buffer));
					SecureZeroMemory(&pdi->m_Overlapped, sizeof(OVERLAPPED));
					if (!ReadDirectoryChangesW(pdi->m_hDir,
												pdi->m_Buffer,
												READ_DIR_CHANGE_BUFFER_SIZE,
												TRUE,
												FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE,
												&numBytes,// not used
												&pdi->m_Overlapped,
												NULL))	//no completion routine!
					{
						// Since the call to ReadDirectoryChangesW failed, just
						// wait a while. We don't want to have this thread
						// running using 100% CPU if something goes completely
						// wrong.
						Sleep(200);
					}
				}
			}
		} // if (watchedPaths.GetCount())
		else
			Sleep(200);
	} // while (m_bRunning)
}
コード例 #18
0
ファイル: main_windows.c プロジェクト: wopl/fhem
// 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(&notification_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(),
		                                                 &notification_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,
		                                                 &notification_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;
}
コード例 #19
0
HRESULT CMSPThread::ThreadProc()
/*++

Routine Description:

    the main loop of this thread.

Arguments:
    
Return Value:

    HRESULT.

--*/
{

    LOG((MSP_TRACE, "CMSPThread::ThreadProc - started"));


    BOOL bExitFlag = FALSE;

    m_hDevNotifyVideo = NULL;
    m_hDevNotifyAudio = NULL;
    m_hWndNotif = NULL;


    HRESULT hr = E_FAIL;

    if (FAILED(hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED)))
    {
        LOG((MSP_ERROR, "CMSPThread::ThreadProc - ConinitialzeEx failed:%x",
            hr));

        return hr;
    }


    //
    // Create a window to receive PNP device notifications. 
    //
    // since this is a base class that is used by more than one msp, we want 
    // to make sure that each msp registers a window class with a unique name
    // 
    // for this reason window class name is derived from threadid.
    //

    DWORD dwThreadID = GetCurrentThreadId();


    //
    // the string needs to be big enough to hold max dword number in hex + 
    // terminating zero. 20 is more than enough.
    //

    TCHAR szWindowClassName[20];

    _stprintf_s(szWindowClassName, _T("%lx"), dwThreadID);


    //
    // configure window class structure for RegisterClass
    //

    WNDCLASS wc;

    ZeroMemory(&wc, sizeof(wc));

    wc.lpfnWndProc = NotifWndProc;
    wc.lpszClassName = szWindowClassName;

    
    //
    // perform the actual registration
    //

    ATOM atomClassRegistration = 0;

    atomClassRegistration = RegisterClass(&wc);

    if (0 == atomClassRegistration)
    {
        LOG((MSP_ERROR, 
            "CMSPThread::ThreadProc - RegisterClass failed, last error %ld", 
            GetLastError()));
        
        hr = E_FAIL;
        goto exit;
    }
    

    //
    // create window that will receive pnp notifications
    //

    m_hWndNotif = CreateWindow(szWindowClassName, _T("MSP PNP Notification Window"), 0,
            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, this);

    if (m_hWndNotif == NULL)
    {
        LOG((MSP_ERROR, "CMSPThread::ThreadProc - can't create notification window"));
        hr = E_FAIL;
        goto exit;
    }


    //
    // success
    //

    LOG((MSP_TRACE, "CMSPThread::ThreadProc - created notification window"));


    //
    // Register to receive PNP device notifications
    //
    DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;

    ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
    NotificationFilter.dbcc_size = 
        sizeof(DEV_BROADCAST_DEVICEINTERFACE);
    NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
    NotificationFilter.dbcc_classguid = AM_KSCATEGORY_VIDEO;

    if ((m_hDevNotifyVideo = RegisterDeviceNotification( m_hWndNotif, 
        &NotificationFilter,
        DEVICE_NOTIFY_WINDOW_HANDLE
        )) == NULL)
    {
        LOG((MSP_ERROR, "CMSPThread::ThreadProc - can't register for video device notification"));
        hr = E_FAIL;
        goto exit;
    }

    NotificationFilter.dbcc_classguid = AM_KSCATEGORY_AUDIO;

    if ((m_hDevNotifyAudio = RegisterDeviceNotification( m_hWndNotif, 
        &NotificationFilter,
        DEVICE_NOTIFY_WINDOW_HANDLE
        )) == NULL)
    {
        LOG((MSP_ERROR, "CMSPThread::ThreadProc - can't register for audio device notification"));
        hr = E_FAIL;
        goto exit;
    }
    
    LOG((MSP_TRACE, "CMSPThread::ThreadProc - registered for PNP device notifications"));

    while (!bExitFlag)
    {
        //
        // Msg:      Grab window messages.
        // Multiple: We only use 1, but Msg and Ex only exist with Multiple.
        // Ex:       Allow flags, so we can pass in MWMO_ALERTABLE.
        //
        
        DWORD dwResult = ::MsgWaitForMultipleObjectsEx(
            1,                // wait for one event
            &m_hCommandEvent, // array of events to wait for
            INFINITE,         // wait forever
            QS_ALLINPUT,      // get all window messages
            MWMO_ALERTABLE    // get APC requests (in case this MSP uses them)
            );

        if ( ( dwResult == WAIT_OBJECT_0 ) || ( dwResult == WAIT_OBJECT_0 + 1 ) )
        {
            LOG((MSP_TRACE, "thread is signaled"));

            m_QueueLock.Lock();
            
            while ( ! IsListEmpty(&m_CommandQueue) )
            {

                LIST_ENTRY * links = RemoveHeadList( &m_CommandQueue );
                
                m_QueueLock.Unlock();
            
                COMMAND_QUEUE_ITEM * pItem =
                    CONTAINING_RECORD(links,
                                      COMMAND_QUEUE_ITEM,
                                      link);

                COMMAND_NODE * pNode = &(pItem->node);

                switch (pNode->cmd)
                {

                case WORK_ITEM:
                
                    LOG((MSP_TRACE, "CMSPThread::ThreadProc - "
                        "got command WORK_ITEM"));

                    pNode->pfn( pNode->pContext );

                    if ( pNode->hEvent != NULL )
                    {
                        if ( SetEvent( pNode->hEvent ) == 0 )
                        {
                            LOG((MSP_ERROR, "CMSPThread::ThreadProc - "
                                "can't signal event for synchronous work "
                                "item"));
                        }
                    }
                    break;

                case STOP:
                    
                    LOG((MSP_TRACE, "CMSPThread::ThreadProc - "
                        "thread is exiting"));

                    bExitFlag = TRUE;
                    break;
                }

                delete pItem;
            
                m_QueueLock.Lock();

            }
            m_QueueLock.Unlock();
            

            //
            // We have processed all commands and unblocked everyone
            // who is waiting for us. Now check for window messages.
            //

            MSG msg;

            // Retrieve the next item in the message queue.

            while ( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
        else if ( dwResult == WAIT_IO_COMPLETION )
        {
            // FEATUREFEATURE: The base MSP does not do anything with APC /
            // async I/O. If the derived MSP does something with it, they must
            // implement this to take appropriate action. Question is, how
            // best to expose this to the derived MSP? We could have a method
            // to override, but then how would the derived thread class get
            // instantiated? Instead, we'll have to have a method to set
            // an async I/O completion callback function pointer.
        }
        else
        {
            LOG((MSP_ERROR, "CMSPThread::ThreadProc - "
                "WaitForMultipleObjects failed  %ld", GetLastError()));

            break;
        }
    }

    hr = S_OK;

exit:

    

    //
    //  cleanup: 
    //
    //  Unregister from PNP device notifications
    //  destroy window
    //  unregister window class
    //  couninitialize
    //


    //
    // unregister from video pnp events if needed
    //

    if ( NULL != m_hDevNotifyVideo )
    {
        HRESULT hr2 = UnregisterDeviceNotification(m_hDevNotifyVideo);

        if (FAILED(hr2))
        {

            LOG((MSP_ERROR,
                "CMSPThread::ThreadProc - UnregisterDeviceNotification failed for video events. "
                "hr = %lx", hr2));
        }
    }

    
    //
    // unregister from audio pnp events if needed
    //

    if ( NULL != m_hDevNotifyAudio )
    {

        HRESULT hr2 = UnregisterDeviceNotification(m_hDevNotifyAudio);

        if (FAILED(hr2))
        {

            LOG((MSP_ERROR, 
                "CMSPThread::ThreadProc - UnregisterDeviceNotification failed for audio events. "
                "hr = %lx", hr2));
        }
    }

    
    //
    // destroy window if needed
    //

    if ( NULL != m_hWndNotif )
    {
        
        BOOL bDestroyWindowSuccess = DestroyWindow(m_hWndNotif);

        if ( ! bDestroyWindowSuccess )
        {
            LOG((MSP_ERROR, 
                "CMSPThread::ThreadProc - DestroyWindow failed. LastError = %ld",
                GetLastError()));
        }
    }


    //
    // unregister window class
    //

    if (0 != atomClassRegistration)
    {

        BOOL bUnregisterSuccess = UnregisterClass( (LPCTSTR)atomClassRegistration, ::GetModuleHandle(NULL) );

        if ( ! bUnregisterSuccess )
        {
            LOG((MSP_ERROR, 
                "CMSPThread::ThreadProc - UnregisterClass failed. LastError = %ld", 
                GetLastError()));
        }
    }


    ::CoUninitialize();

    LOG((MSP_(hr), "CMSPThread::ThreadProc - exit. hr = 0x%lx", hr));

    return hr;
}
コード例 #20
0
MainWindow::MainWindow(void):
wxFrame(NULL, wxID_ANY, wxString(wxT("CNC – øídicí systém")), wxDefaultPosition, wxSize(1000, 600), wxDEFAULT_FRAME_STYLE | wxMAXIMIZE)
{
	//Naètení ikony hlavního okna
	wxIcon icon(wxT("IDI_ICON1"), wxBITMAP_TYPE_ICO_RESOURCE);
	if(!icon.IsOk())
	{
		PostErrorMessage(wxT("Nepodaøilo ase naèíst ikonu hlavního okna"));
	}
	SetIcon(icon);
	//StatusBar
	statusBar = CreateStatusBar(4);
	statusBar->SetStatusText(wxT("Nepøipojeno k intepolátoru"), 0);
	statusBar->SetStatusText(wxT("Žádný program"), 1);
	statusBar->SetStatusText(wxT("Neznámá pozice"), 2);
	statusBar->SetStatusText(wxT("Stav neurèen"), 3);
	//Menu
	menu = new wxMenuBar;
	file = new wxMenu;
	file->Append(wxID_OPEN, wxT("Otevøít soubor s intrukcemi"), wxT("Otevøít soubor s programem"), false);
	file->Append(ID_OPEN_GCODE, wxT("Otevøít G-kód"), wxT("Otevøít soubor s programem"), false);
	file->Append(wxID_EXIT, wxT("&Konec"));
	menu->Append(file, wxT("&Soubor"));
	view = new wxMenu;
	view->Append(ID_RESETVIEW, wxT("Resetovat zobrazení drah"), wxT("Obnoví zobrazení"), false);
	view->Append(ID_RESETTRAJECTORY, wxT("Smazat stopu"), wxT("Smaže stopu nástroje"), false);
	view->Append(ID_TOGGLETRAJECTORY, wxT("Vypnout/zapnout stopu"), wxT(""), false);
	menu->Append(view, wxT("&Náhled"));
	SetMenuBar(menu);
	//Connect menus and buttons to the functions
	Connect(wxID_OPEN, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainWindow::OnOpen));
	Connect(ID_OPEN_GCODE, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainWindow::OnOpenGcode));
	Connect(ID_RESETVIEW, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainWindow::OnViewReset));
	Connect(ID_RESETTRAJECTORY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainWindow::OnTrajectoryReset));
	Connect(ID_TOGGLETRAJECTORY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainWindow::OnTrajectoryToggle));
	//Toolbar
	toolbar = CreateToolBar();
	toolbar->SetToolBitmapSize(wxSize(48, 48));
	toolbar->AddSeparator();
	toolbar->AddTool(2, wxBitmap(wxT("IDB_STARTPROGRAM"), wxBITMAP_TYPE_BMP_RESOURCE), wxT("Spustit program"));
	toolbar->AddTool(3, wxBitmap(wxT("IDB_PAUSEPROGRAM"), wxBITMAP_TYPE_BMP_RESOURCE), wxT("Pozastavit program"));
	toolbar->AddTool(4, wxBitmap(wxT("IDB_STOPPROGRAM"), wxBITMAP_TYPE_BMP_RESOURCE), wxT("Zastavit program"));
	toolbar->Realize();
	toolbar->EnableTool(1, false);
	toolbar->EnableTool(3, false);
	toolbar->EnableTool(4, false);
	SetStatusBarPane(-1);
	//Connect icons to the function
	Connect(2, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler(MainWindow::OnRunProgram));
	Connect(3, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler(MainWindow::OnPauseProgram));
	Connect(4, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler(MainWindow::OnStopProgram));

	//Splitter window
	topSplit = new wxSplitterWindow(this);
	//Content of the left
	leftPanel = new wxPanel(topSplit, 0, 0, 150, 150);
	//Content of the right
	downSplit = new wxSplitterWindow(topSplit);
	//Content of the downSplit
	middlePanel = new PreviewWindow(downSplit, 0, 0, 150, 150);
	rightPanel = new wxPanel(downSplit, 0, 0, 150, 150);
	//Split the windows
	topSplit->SplitVertically(leftPanel, downSplit, 250);
	downSplit->SplitVertically(middlePanel, rightPanel, -300);
	middlePanel->Reset();
	topSplit->SetSashGravity(0);
	downSplit->SetSashGravity(1);
	topSplit->SetMinimumPaneSize(150);
	downSplit->SetMinimumPaneSize(200);

	//Content of the right panel
	codeView = new wxTextCtrl(rightPanel, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_AUTO_SCROLL | wxTE_READONLY | wxTE_RICH2 | wxHSCROLL | wxTE_NOHIDESEL);
	wxBoxSizer *sizeRight = new wxBoxSizer(wxVERTICAL);
	sizeRight->Add(codeView, 1, wxEXPAND | wxALL, 0);
	rightPanel->SetSizer(sizeRight);

	//Set the font
	wxFont codeFont(15, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL,wxFONTWEIGHT_NORMAL, false);
	codeView->SetDefaultStyle(wxTextAttr(wxColour((unsigned long)(0)), wxNullColour, codeFont));
	
	//Initialization of USB - receivng messages obaout device state
	HWND hwnd = HWND(GetHWND());
	DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
    ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
    NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
    NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
    NotificationFilter.dbcc_classguid = DEVICE_INTERFACE;
	if(!RegisterDeviceNotification(hwnd, (void*)(&NotificationFilter), DEVICE_NOTIFY_WINDOW_HANDLE))
	{
		wxString err;
		err << wxT("Chyba pøi incializaci notifikace pro zaøízení - chyba ")  << GetLastError();
		PostErrorMessage(err);
	}

	//Centre window
	Center();
	Maximize();
	middlePanel->Reset();
}
コード例 #21
0
bool DeviceStatus::Initialize()
{

	WNDCLASS wndClass;
	wndClass.style         = CS_HREDRAW | CS_VREDRAW;
	wndClass.lpfnWndProc   = WindowsMessageCallback;
	wndClass.cbClsExtra    = 0;
	wndClass.cbWndExtra    = 0;
	wndClass.hInstance     = 0;
	wndClass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
	wndClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
	wndClass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
	wndClass.lpszMenuName  = NULL;
	wndClass.lpszClassName = windowClassName;

	if (!RegisterClass(&wndClass))
	{
		OVR_ASSERT_LOG(false, ("Failed to register window class."));
		return false;
	}

    // We're going to create a 'message-only' window. This will be hidden, can't be enumerated etc.
    // To do this we supply 'HWND_MESSAGE' as the hWndParent.
    // http://msdn.microsoft.com/en-us/library/ms632599%28VS.85%29.aspx#message_only
	hMessageWindow = CreateWindow(	windowClassName,
									windowClassName,
									WS_OVERLAPPEDWINDOW,
									CW_USEDEFAULT,
									CW_USEDEFAULT,
									CW_USEDEFAULT,
									CW_USEDEFAULT,
									HWND_MESSAGE,
									NULL,
									0,
									this);	// Pass this object via the CREATESTRUCT mechanism 
                                            // so that we can attach it to the window user data.

    if (hMessageWindow == NULL)
	{
		OVR_ASSERT_LOG(false, ("Failed to create window."));
		return false;
	}

    // According to MS, topmost windows receive WM_DEVICECHANGE faster.
	::SetWindowPos(hMessageWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
	UpdateWindow(hMessageWindow);


	// Register notification for additional HID messages.
    HIDDeviceManager* hidDeviceManager = new HIDDeviceManager(NULL);
	HidGuid = hidDeviceManager->GetHIDGuid();
    hidDeviceManager->Release();

	DEV_BROADCAST_DEVICEINTERFACE notificationFilter;

	ZeroMemory(&notificationFilter, sizeof(notificationFilter));
	notificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
	notificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
	//notificationFilter.dbcc_classguid = hidguid;

    // We need DEVICE_NOTIFY_ALL_INTERFACE_CLASSES to detect
    // HDMI plug/unplug events.
	hDeviceNotify = RegisterDeviceNotification(	
        hMessageWindow,
		&notificationFilter,
		DEVICE_NOTIFY_ALL_INTERFACE_CLASSES|DEVICE_NOTIFY_WINDOW_HANDLE);

	if (hDeviceNotify == NULL)
	{
		OVR_ASSERT_LOG(false, ("Failed to register for device notifications."));
		return false;
	}

	return true;
}
コード例 #22
0
ファイル: inf_wizard.c プロジェクト: markzh2015/aboutusb
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;
}
コード例 #23
0
ファイル: hidapi_ext_win.cpp プロジェクト: Finlod/Lohi
//TODO: add filtering to event monitor
hid_event_monitor* hid_create_event_monitor() {
	WNDCLASSEX wx;
	ZeroMemory(&wx, sizeof(wx));

	wx.cbSize = sizeof(WNDCLASSEX);
	wx.lpfnWndProc = (WNDPROC)(WindowProc);
	wx.hInstance = GetModuleHandle(0);
	wx.lpszClassName = L"hidapi_ext_win32";

	ATOM class_ret = RegisterClassEx(&wx);

	if (!class_ret) {
		DWORD last_error = GetLastError();
		printf("hid_create_event_monitor failed, RegisterClassEx failed, last error: %ul", last_error);
		return NULL;
	}

	HWND hwnd = CreateWindow(L"hidapi_ext_win32", L"hidapi_ext_dev_monitor",
							 WS_ICONIC, 0, 0, 0, 0, HWND_MESSAGE,
							 NULL, GetModuleHandle(0), NULL);

	if (!hwnd) {
		DWORD last_error = GetLastError();
		printf("hid_create_event_monitor failed, CreateWindow failed, last error: %ul", last_error);
		return NULL;
	}

	hid_event_monitor* monitor = (hid_event_monitor*)malloc(sizeof(hid_event_monitor));
	monitor->hwnd = hwnd;
	monitor->proc_real_event = false;

	monitor->proc_event = {};
	monitor->proc_event.device_info = (hid_device_info*)malloc(sizeof(hid_device_info));
	memset(monitor->proc_event.device_info, 0, sizeof(*monitor->proc_event.device_info));

	//SetWindowLongPtr will return 0 if previous return value was 0
	SetLastError(0);

	//This is a way to get monitor ptr to WindowProc
	LONG_PTR window_ptr_ret = SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)monitor);

	DWORD last_error = GetLastError();

	if (!window_ptr_ret && last_error) {
		printf("hid_create_event_monitor failed, SetWindowLongPtr failed, last error: %ul", last_error);

		hid_free_event_monitor(monitor);
		return NULL;
	}

	//GUID_DEVINTERFACE_HID
	GUID deviceinterface_hid_guid = { 0x4d1e55b2, 0xf16f, 0x11cf, 0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30};

	DEV_BROADCAST_DEVICEINTERFACE broadcast_deviceinterface;
	ZeroMemory(&broadcast_deviceinterface, sizeof(broadcast_deviceinterface));

	broadcast_deviceinterface.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
	broadcast_deviceinterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
	broadcast_deviceinterface.dbcc_classguid = deviceinterface_hid_guid;

	HDEVNOTIFY dev_notify = RegisterDeviceNotification(hwnd, &broadcast_deviceinterface, DEVICE_NOTIFY_WINDOW_HANDLE);

	if (!dev_notify) {
		DWORD last_error = GetLastError();
		printf("hid_create_event_monitor failed, RegisterDeviceNotification failed, last error: %ul", last_error);

		hid_free_event_monitor(monitor);
		return NULL;
	}

	monitor->dev_notify = dev_notify;

	return monitor;
}
コード例 #24
0
int setupDInput()
{
	if (!diAvailable) {
		return FALSE;
	}
	// Create a DirectInput8 instance
	if (di != NULL) {
		return TRUE;
	}
	HRESULT hr = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&di, NULL);
	if (FAILED(hr)) {
		// If it is not available for any reason, avoid getting back in setupDInput
		diAvailable = false;
		MessageBox(NULL, GetLastErrorAsString().c_str(), "SF5DInput - Direct Input", MB_ICONERROR);
		exit(hr);
	}

	// DI is ready, now create a message-only window
	WNDCLASSEX wndClass = {};
	wndClass.cbSize = sizeof(WNDCLASSEX);
	wndClass.lpfnWndProc = reinterpret_cast<WNDPROC>(messageCallback);
	GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)&wndClass.hInstance, &wndClass.hInstance);
	wndClass.lpszClassName = "SF5DInput";

	if (!RegisterClassEx(&wndClass)) {
		MessageBox(NULL, GetLastErrorAsString().c_str(), "SF5DInput - Registering Window Class", MB_ICONERROR);
		exit(1);
	}

	hWnd = CreateWindowEx(0L, wndClass.lpszClassName, "SF5DInput", 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);	
	if (!hWnd) {
		MessageBox(NULL, GetLastErrorAsString().c_str(), "SF5DInput - Create Internal Window", MB_ICONERROR);
		exit(2);
	}

	// Message only window is ready, now we can create a notification filter to register to device notificaitons

	DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;

	ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
	NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
	NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
	// This is GUID_DEVINTERFACE_USB_DEVICE, it scans all usb devices
	NotificationFilter.dbcc_classguid = { 0xA5DCBF10L, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } };

	hDeviceNotify = RegisterDeviceNotification(
		hWnd,                       // events recipient
		&NotificationFilter,        // type of device
		DEVICE_NOTIFY_WINDOW_HANDLE // type of recipient handle
	);

	if (NULL == hDeviceNotify) {
		MessageBox(NULL, GetLastErrorAsString().c_str(), "SF5DInput - Registering Device Notification", MB_ICONERROR);
		exit(1);
	}

	// WOOH we are ready to go!

	// Get all the devices
	refreshDevices();
	return TRUE;
}
コード例 #25
0
ファイル: AbstractGattService.cpp プロジェクト: uri247/wdk80
HRESULT 
AbstractGattService::StartMessagePump()
{
    HRESULT hr = S_OK;
    DEV_BROADCAST_HANDLE dbh = {0};

    //
    // Start a new thread to implement the message pump
    //
    m_hMessagePumpInitialized = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (NULL == m_hMessagePumpInitialized)
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        CHECK_HR(hr, "Failed to create the message pump initialized event");
    }

    if (SUCCEEDED(hr))
    {
        //
        // Create the terminate event
        //
        m_hMessagePumpTerminate = CreateEvent(NULL, FALSE, FALSE, NULL);
        if (NULL == m_hMessagePumpTerminate)
        {
            hr = HRESULT_FROM_WIN32(GetLastError());
            CloseHandle(m_hMessagePumpInitialized);
            m_hMessagePumpInitialized = NULL;
            CHECK_HR(hr, "Failed to create the message pump terminate event");
        }
    }


    if (SUCCEEDED(hr))
    {
        //
        // Create the thread and wait for it to be initialized
        //
        m_hMessagePumpThread = CreateThread(NULL,
                                        0,
                                        s_MessagePumpThreadProc,
                                        (LPVOID)this,
                                        0,
                                        NULL);
        if (NULL == m_hMessagePumpThread)
        {
            
            hr = HRESULT_FROM_WIN32(GetLastError());
            
            CloseHandle(m_hMessagePumpInitialized);
            m_hMessagePumpInitialized = NULL;
            
            CloseHandle(m_hMessagePumpTerminate);
            m_hMessagePumpTerminate = NULL;
            CHECK_HR(hr, "Failed to create the message pump thread");
        }
    }

    if (SUCCEEDED(hr))
    {
        WaitForSingleObject(m_hMessagePumpInitialized, INFINITE);
        hr = m_hrMessagePumpStartStatus;
        CHECK_HR(hr, "Failed to start the message pump");
    }


    //
    // Register for device change notifications
    //
    if (SUCCEEDED(hr))
    {
        dbh.dbch_size = sizeof(dbh);
        dbh.dbch_devicetype = DBT_DEVTYP_HANDLE;
        dbh.dbch_handle = m_hRadioHandle;
        m_hDevNotification = RegisterDeviceNotification(m_hWnd, &dbh, DEVICE_NOTIFY_WINDOW_HANDLE);
        if (NULL == m_hDevNotification)
        {
            hr = HRESULT_FROM_WIN32(GetLastError());
            CHECK_HR(hr, "Failed to register for device notifications");
        }        
    }

    return hr;
}
コード例 #26
0
SweetDisplayStandby::SweetDisplayStandby(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::SweetDisplayStandby)
{

    displayWasDimmed = false;
    displayWasTurnedOff = false;
    forceDisplayTurnOff = false;
    turnOffHotKeyId = 1;
    restoreHotKeyId = 2;
    lastInputTime = 0;
    const GUID GUID_DEVINTERFACE_MONITOR = {0xe6f07b5f, 0xee97, 0x4a90, 0xb0, 0x76, 0x33, 0xf5, 0x7b, 0xf4, 0xea, 0xa7};


    ui->setupUi(this);

    appIcon = QIcon(":/main/icon.png");

    QStringList arguments = QCoreApplication::arguments();
    createTrayIcon();
    setWindowFlags(Qt::WindowTitleHint | Qt::WindowSystemMenuHint |Qt:: WindowMinimizeButtonHint | Qt::WindowCloseButtonHint  | Qt::MSWindowsFixedSizeDialogHint );

    QCoreApplication::setOrganizationName("Vavooon");
    QCoreApplication::setApplicationName("SweetDisplayStandby");
    settings = new QSettings();
    displayDimTime = settings->value("dimTime", 30).toInt();
    displayOffTime = settings->value("turnOffTime", 3*60).toInt();
    normalBrightnessLevel = settings->value("normalBrightnessLevel", 60).toInt();
    dimmedBrightnessLevel = settings->value("dimmedBrightnessLevel", 0).toInt();
    enableBrighnessManagement = settings->value("enableBrighnessManagement", true).toBool();
    autoStartup = settings->value("autoStartup", false).toBool();
    showTrayIcon = settings->value("showTrayIcon", true).toBool();
    runMinimized = settings->value("runMinimized", true).toBool();
    turnOffSequence = QKeySequence( settings->value("turnOffSequence", "Ctrl+F1").toString() );
    restoreSequence = QKeySequence( settings->value("restoreSequence", "Ctrl+F12").toString() );

    ui->dimTimeInput->setValue( displayDimTime );
    ui->turnOffTimeInput->setValue( displayOffTime );
    ui->normalBrightnessLevelInput->setValue( normalBrightnessLevel );
    ui->dimmedBrightnessLevelInput->setValue( dimmedBrightnessLevel );
    ui->brightnessStateCheckBox->setChecked( enableBrighnessManagement );
    ui->brightnessGroupBox->setEnabled(enableBrighnessManagement);
    ui->dimTimeInput->setEnabled(enableBrighnessManagement);
    ui->startupCheckBox->setChecked(autoStartup);
    ui->trayCheckBox->setChecked(showTrayIcon);
    ui->minimizedCheckBox->setChecked(runMinimized);

    ui->statusBar->showMessage("Display is active");

    connect( ui->actionAbout, SIGNAL(triggered(bool)), this, SLOT(aboutPopup()));
    connect( ui->actionProjectSite, SIGNAL(triggered(bool)), this, SLOT(openSite()) );
    connect( ui->actionExit, SIGNAL(triggered(bool)), this, SLOT( exit() ) );

    connect( ui->dimTimeInput, SIGNAL(valueChanged(int)), this, SLOT( onDimTimeChange(int)) );
    connect( ui->turnOffTimeInput, SIGNAL(valueChanged(int)), this, SLOT( onTurnOffTimeChange(int)) );
    connect( ui->normalBrightnessLevelInput, SIGNAL( valueChanged(int)), this, SLOT(onNormalBrightnessLevelChange(int)) );
    connect( ui->dimmedBrightnessLevelInput, SIGNAL( valueChanged(int)), this, SLOT(onDimmedBrightnessLevelChange(int)) );
    connect( ui->brightnessStateCheckBox, SIGNAL(toggled(bool)), this, SLOT(onBrightnessStateChange(bool)) );
    connect( ui->startupCheckBox, SIGNAL(toggled(bool)), this, SLOT(onStartupCheckBox(bool)) );
    connect( ui->trayCheckBox, SIGNAL(toggled(bool)), this, SLOT(onTrayCheckBox(bool)) );
    connect( ui->minimizedCheckBox, SIGNAL( toggled(bool)), this, SLOT(onMinimizeCheckBox(bool)) );
//    connect( ui->allDisplaysRadio, SIGNAL(toggled(bool)), ui->displaysList, SLOT(setEnabled(bool)) );

    connect( ui->turnOffSequenceEdit, SIGNAL(keySequenceChanged(QKeySequence)), this, SLOT(updateTurnOffSequence(QKeySequence)) );
    connect( ui->restoreSequenceEdit, SIGNAL(keySequenceChanged(QKeySequence)), this, SLOT(updateRestoreSequence(QKeySequence)) );

    ui->turnOffSequenceEdit->setKeySequence(turnOffSequence);
    ui->restoreSequenceEdit->setKeySequence(restoreSequence);

    EnumDisplayMonitors(0, 0, EnumProc, 0);


    DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
    ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));

    NotificationFilter.dbcc_size = sizeof(NotificationFilter);
    NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
    NotificationFilter.dbcc_reserved = 0;

    NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_MONITOR;

    RegisterDeviceNotification((HWND)SweetDisplayStandby::winId(),&NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE );



    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(timerTick()));
    timer->setInterval(100);
    timer->start();

    QTimer *tickTimer = new QTimer(this);
    tickTimer->setInterval(1000);
    connect(tickTimer, SIGNAL(timeout()), this, SLOT(queueTimerTick()));
    tickTimer->start();

    addToQueue("turnOn");
    addToQueue("illuminate");


    if (showTrayIcon)
    {
        trayIcon->show();
    }

    if (!runMinimized)
    {
        show();
    }
}
コード例 #27
0
ファイル: LBTService.cpp プロジェクト: daemongloom/LBTService
//
// Purpose: 
//   The service code
//
// Parameters:
//   dwArgc - Number of arguments in the lpszArgv array
//   lpszArgv - Array of strings. The first string is the name of
//     the service and subsequent strings are passed by the process
//     that called the StartService function to start the service.
// 
// Return value:
//   None
//
VOID SvcInit( DWORD dwArgc, LPTSTR *lpszArgv)
{
	// TO_DO: Declare and set any required variables.
	//   Be sure to periodically call ReportSvcStatus() with 
	//   SERVICE_START_PENDING. If initialization fails, call
	//   ReportSvcStatus with SERVICE_STOPPED.

	// Create an event. The control handler function, SvcCtrlHandler,
	// signals this event when it receives the stop control code.

	ghSvcStopEvent = CreateEvent(
		NULL,    // default security attributes
		TRUE,    // manual reset event
		FALSE,   // not signaled
		NULL);   // no name

	if ( ghSvcStopEvent == NULL)
	{
		ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 );
		return;
	}

	if ( !LoadSupportedBluetoothDevices() )
	{
		ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 );
		return;
	}

	GUID hidGuid;
	HidD_GetHidGuid(&hidGuid);

	DEV_BROADCAST_DEVICEINTERFACE dbvNotificationFilter;

	ZeroMemory( &dbvNotificationFilter, sizeof(dbvNotificationFilter) );
	dbvNotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
	dbvNotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
	dbvNotificationFilter.dbcc_classguid = hidGuid;

	HDEVNOTIFY hDeviceNotification = RegisterDeviceNotification( 
		gSvcStatusHandle, &dbvNotificationFilter, DEVICE_NOTIFY_SERVICE_HANDLE );

	if ( hDeviceNotification == NULL)
	{
		ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 );
		return;
	}

	TryToSwitchAllDevices( TRUE );

	// Report running status when initialization is complete.
	ReportSvcStatus( SERVICE_RUNNING, NO_ERROR, 0 );

	while(1)
	{
		// Check whether to stop the service.
		WaitForSingleObject(ghSvcStopEvent, INFINITE);
		break;
	}

	UnregisterDeviceNotification(hDeviceNotification);
	ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 );
}
コード例 #28
0
ファイル: main_windows.c プロジェクト: Loremipsum1988/brickd
// 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(&notification_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(),
		                                                 &notification_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,
		                                                 &notification_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;
}
コード例 #29
0
DWORD WINAPI discoveryWindow(LPVOID lpParam) {
    DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
    GUID HidGuid;					/* temporarily stores Windows HID Class GUID */
    MSG event;
    WNDCLASSEX* wndclass = freespace_instance_->wndclass_;

    // Register the hidden window class
    if (wndclass == NULL) {
        wndclass = (WNDCLASSEX*) malloc(sizeof(WNDCLASSEX));
        memset (wndclass, 0, sizeof(WNDCLASSEX));
        wndclass->cbSize = sizeof(WNDCLASSEX);
        wndclass->style = CS_HREDRAW | CS_VREDRAW;
        wndclass->lpfnWndProc = discoveryCallback;
        wndclass->hInstance = 0;
        wndclass->hIcon = LoadIcon (NULL, IDI_APPLICATION);
        wndclass->hCursor = LoadCursor (NULL, IDC_ARROW);
        wndclass->hbrBackground = (HBRUSH)(COLOR_WINDOW+1);

        wndclass->lpszClassName = szMainWndClass;
        wndclass->hIconSm = LoadIcon (NULL, IDI_APPLICATION);

        if (!RegisterClassEx(wndclass)) {
            freespace_instance_->discoveryTheadStatus_ = FREESPACE_ERROR_UNEXPECTED;
            return 0;
        }
        freespace_instance_->wndclass_ = wndclass;
    }

    freespace_instance_->window_ = CreateWindow (
                                                 szMainWndClass,				/* Class name */
                                                 szMainWndClass,				/* Caption */
                                                 WS_OVERLAPPEDWINDOW,        /* Style */
                                                 CW_USEDEFAULT,              /* Initial x (use default) */
                                                 CW_USEDEFAULT,              /* Initial y (use default) */
                                                 CW_USEDEFAULT,              /* Initial x size (use default) */
                                                 CW_USEDEFAULT,              /* Initial y size (use default) */
                                                 NULL,					    /* No parent window */
                                                 NULL,                       /* No menu */
                                                 0,                          /* This program instance */
                                                 NULL);                      /* Creation parameters */

    if (freespace_instance_->window_ == NULL) {
        // We have a problem
        freespace_instance_->discoveryTheadStatus_ = FREESPACE_ERROR_UNEXPECTED;
        return 0;
    }

    /* Hide the window.  Have to manually close it later by posting a
     * WM_CLOSE event
     */
    ShowWindow (freespace_instance_->window_, SW_HIDE /*SW_SHOW*/);
    UpdateWindow (freespace_instance_->window_);

    /* Set up device notification of plug or unplug of HID Devices */

    /* 1) get the HID GUID */
    // WARNING: we currently only monitor HID devices
    HidD_GetHidGuid(&HidGuid);

    /* 2) clear the notification filter */
    ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));

    /* 3) assign the previously cleared structure with the correct data
       so that the application is notified of HID device un/plug events */
    NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
    NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
    NotificationFilter.dbcc_classguid = HidGuid;

    /* 4) register device notifications for this application */
    freespace_instance_->windowEvent_ = RegisterDeviceNotification(freespace_instance_->window_,
                                                                   &NotificationFilter,
                                                                   DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES );

    /* 5) notify the calling procedure if the HID device will not be recognized */
    if (!freespace_instance_->windowEvent_) {
        // Somehow cleanup after this...
        freespace_instance_->discoveryTheadStatus_ = FREESPACE_ERROR_UNEXPECTED;
        return 0;
    }

    // A blocking loop to retrieve events
    while (GetMessage(&event, NULL, 0, 0)) {
        TranslateMessage(&event);
        DispatchMessage(&event);
    }

    // Unregister the hidden window class
    if (!UnregisterClass(freespace_instance_->wndclass_->lpszClassName, 
                         freespace_instance_->wndclass_->hInstance)) {
        DEBUG_PRINTF("Could not unregister window: %d\n", GetLastError());
    } else {
        free(wndclass);
        freespace_instance_->wndclass_ = NULL;
    }

    freespace_instance_->window_ = NULL;

    return 0;
}
/* This thread keep polling for the physical existence of a port/file/device. When port removal is detected, this
* informs java listener and exit. Associate the handler with a class, that class with a window and register that
* window with notification system. */
unsigned __stdcall usb_device_hotplug_monitor(void *arg) {

	int i = 0;
	int ret = 0;
	BOOL result = FALSE;
	DWORD errorVal = 0;
	MSG msg;
	ATOM atom;
	HDEVNOTIFY notification_handle = NULL;
	DEV_BROADCAST_DEVICEINTERFACE dev_broadcast_iface;
	HWND window_handle;
	WNDCLASSEX wndClass = { 0 };
	HINSTANCE hInstance;
	TCHAR classname_buf[64];

	struct usb_dev_monitor_info* ptr = (struct usb_dev_monitor_info*) arg;
	jmethodID onUSBHotPlugEventMethodID = NULL;
	jclass usbHotPlugEventListenerClass = NULL;
	jobject usbHotPlugEventListenerObj = (*ptr).usbHotPlugEventListener;
	JavaVM *jvm = (*ptr).jvm;
	JNIEnv* env = NULL;
	void* env1 = NULL;

	EnterCriticalSection(((struct usb_dev_monitor_info*) arg)->csmutex);

	/* USB device (excluding hub and host controller) */
	const GUID GUID_DEVINTERFACE_USB_DEVICE = { 0xA5DCBF10, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED };

	if ((*jvm)->AttachCurrentThread(jvm, &env1, NULL) != JNI_OK) {
		((struct  usb_dev_monitor_info*) arg)->custom_err_code = E_ATTACHCURRENTTHREAD;
		((struct usb_dev_monitor_info*) arg)->init_done = 2;
		LeaveCriticalSection(((struct usb_dev_monitor_info*) arg)->csmutex);
		return 0;
	}
	env = (JNIEnv*)env1;

	usbHotPlugEventListenerClass = (*env)->GetObjectClass(env, usbHotPlugEventListenerObj);
	if ((usbHotPlugEventListenerClass == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
		((struct usb_dev_monitor_info*) arg)->custom_err_code = E_GETOBJECTCLASS;
		((struct usb_dev_monitor_info*) arg)->init_done = 2;
		(*jvm)->DetachCurrentThread(jvm);
		LeaveCriticalSection(((struct usb_dev_monitor_info*) arg)->csmutex);
		/* For unrecoverable errors we would like to exit and try registering again. */
		return 0;
	}

	onUSBHotPlugEventMethodID = (*env)->GetMethodID(env, usbHotPlugEventListenerClass, "onUSBHotPlugEvent", "(I)V");
	if ((onUSBHotPlugEventMethodID == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
		((struct usb_dev_monitor_info*) arg)->custom_err_code = E_GETMETHODID;
		((struct usb_dev_monitor_info*) arg)->init_done = 2;
		(*jvm)->DetachCurrentThread(jvm);
		LeaveCriticalSection(((struct usb_dev_monitor_info*) arg)->csmutex);
		return 0;
	}

	/* Registers a window class for subsequent use in calls to the CreateWindow or CreateWindowEx function.  */
	memset(classname_buf, '\0', 64);
	_stprintf_s(classname_buf, 64, TEXT("SCM USB : %p"), ((struct usb_dev_monitor_info*) arg)->thread_handle);
	hInstance = (HINSTANCE)GetModuleHandle(NULL);
	wndClass.cbSize = sizeof(WNDCLASSEX);
	wndClass.style = 0;
	wndClass.lpfnWndProc = (WNDPROC)usb_hotplug_event_handler;
	wndClass.cbClsExtra = 0;
	wndClass.cbWndExtra = 0;
	wndClass.hInstance = hInstance;
	wndClass.hIcon = NULL;
	wndClass.hCursor = NULL;
	wndClass.hbrBackground = NULL;
	wndClass.lpszMenuName = NULL;
	wndClass.lpszClassName = classname_buf;
	wndClass.hIconSm = NULL;
	atom = RegisterClassEx(&wndClass);
	if (atom == 0) {
		/* should not happen, just log it for later analysis */
		LOGEN("RegisterClassEx() failed in ", "usb_device_hotplug_monitor() with Windows error code : ", GetLastError());
	}

	/* Create message only window.  Windows will deliver messages to this window. */
	window_handle = CreateWindowEx(WS_EX_TOPMOST, classname_buf, TEXT("scm usb hot plug event thread window"), 0,
									0, 0, 0, 0, HWND_MESSAGE, 0, 0, 0);
	if (window_handle == NULL) {
		UnregisterClass(wndClass.lpszClassName, hInstance);
		((struct usb_dev_monitor_info*) arg)->standard_err_code = GetLastError();
		((struct usb_dev_monitor_info*) arg)->init_done = 2;
		(*jvm)->DetachCurrentThread(jvm);
		LeaveCriticalSection(((struct usb_dev_monitor_info*) arg)->csmutex);
		return 0;
	}

	/* Register with the system to receive device notifications. */
	SecureZeroMemory(&dev_broadcast_iface, sizeof(dev_broadcast_iface));
	dev_broadcast_iface.dbcc_size = sizeof(dev_broadcast_iface);
	dev_broadcast_iface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
	dev_broadcast_iface.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;
	notification_handle = RegisterDeviceNotification(window_handle,                /* events recipient window */
													&dev_broadcast_iface,          /* type of device for which notification will be sent */
													DEVICE_NOTIFY_WINDOW_HANDLE);  /* type of recipient handle */
	if (notification_handle == NULL) {
		DestroyWindow(window_handle);
		UnregisterClass(wndClass.lpszClassName, hInstance);
		((struct usb_dev_monitor_info*) arg)->standard_err_code = GetLastError();
		((struct usb_dev_monitor_info*) arg)->init_done = 2;
		(*jvm)->DetachCurrentThread(jvm);
		LeaveCriticalSection(((struct usb_dev_monitor_info*) arg)->csmutex);
		return 0;
	}

	/* Save so that event callback function can use them. */
	usbport_monitor_info_ptr = ((struct usb_dev_monitor_info*) arg)->info;
	((struct usb_dev_monitor_info*) arg)->env = env;
	((struct usb_dev_monitor_info*) arg)->onUSBHotPlugEventMethodID = onUSBHotPlugEventMethodID;
	((struct usb_dev_monitor_info*) arg)->window_handle = window_handle;

	/* indicate success to the caller so it can return success to java layer */
	((struct usb_dev_monitor_info*) arg)->init_done = 0;
	LeaveCriticalSection(((struct usb_dev_monitor_info*) arg)->csmutex);

	/* message loop */
	while (1) {
		/* block until there is a message in the queue. */
		result = GetMessage(&msg, NULL, 0, 0);
		if (result > 0) {
			if (((struct usb_dev_monitor_info*) arg)->thread_exit == 1) {
				/* application wish to unregister usb hot plug listener, get out of loop and exit thread */
				break;
			}
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}else if (result == 0) {
			/* WM_QUIT received, get out of loop and exit thread */
			break;
		}else {
			/* should not happen, just log it for later analysis */
			LOGEN("GetMessage() failed in ", "usb_device_hotplug_monitor() with Windows error code : %d", GetLastError());
		}
	}

	UnregisterDeviceNotification(notification_handle);
	DestroyWindow(window_handle);
	UnregisterClass(wndClass.lpszClassName, hInstance);
	(*jvm)->DetachCurrentThread(jvm);
	return 0;
}