Beispiel #1
0
EVQ_API int
evq_add_dirwatch (struct event_queue *evq, struct event *ev, const char *path)
{
    const DWORD flags = FILE_NOTIFY_CHANGE_FILE_NAME
     | FILE_NOTIFY_CHANGE_DIR_NAME
     | FILE_NOTIFY_CHANGE_ATTRIBUTES
     | FILE_NOTIFY_CHANGE_SIZE
     | FILE_NOTIFY_CHANGE_LAST_WRITE
     | FILE_NOTIFY_CHANGE_CREATION
     | FILE_NOTIFY_CHANGE_SECURITY;
    const unsigned int filter = (ev->flags >> EVENT_EOF_SHIFT_RES)
     ? FILE_NOTIFY_CHANGE_LAST_WRITE : flags;
    HANDLE fd;

    ev->flags &= ~EVENT_EOF_MASK_RES;

    {
	void *os_path = utf8_to_filename(path);
	if (!os_path)
	    return -1;

	fd = is_WinNT
	 ? FindFirstChangeNotificationW(os_path, FALSE, filter)
	 : FindFirstChangeNotificationA(os_path, FALSE, filter);

	free(os_path);
    }
    if (fd == NULL || fd == INVALID_HANDLE_VALUE)
	return -1;

    ev->fd = fd;
    return evq_add(evq, ev);
}
QStringList QWindowsFileSystemWatcherEngine::addPaths(const QStringList &paths,
                                                      QStringList *files,
                                                      QStringList *directories)
{
    if (handles.isEmpty() || handles.count() == MAXIMUM_WAIT_OBJECTS)
        return paths;

    QMutexLocker locker(&mutex);

    QStringList p = paths;
    QMutableListIterator<QString> it(p);
    while (it.hasNext()) {
        QString path = it.next();
        QString normalPath = path;
        if (normalPath.endsWith(QLatin1Char('/')) || normalPath.endsWith(QLatin1Char('\\')))
            normalPath.chop(1);
        QFileInfo fileInfo(normalPath.toLower());
        if (!fileInfo.exists())
            continue;

        bool isDir = fileInfo.isDir();
        if (isDir) {
            if (directories->contains(path))
                continue;
        } else {
            if (files->contains(path))
                continue;
        }

        const QString absolutePath = isDir ? fileInfo.absoluteFilePath() : fileInfo.absolutePath();
        HANDLE handle = handleForDir.value(absolutePath, INVALID_HANDLE_VALUE);
        if (handle == INVALID_HANDLE_VALUE) {
            QT_WA({
                handle = FindFirstChangeNotificationW((TCHAR *) absolutePath.utf16(),
                                                      false,
                                                      (FILE_NOTIFY_CHANGE_DIR_NAME
                                                       | FILE_NOTIFY_CHANGE_FILE_NAME
                                                       | FILE_NOTIFY_CHANGE_ATTRIBUTES
                                                       | FILE_NOTIFY_CHANGE_SIZE
                                                       | FILE_NOTIFY_CHANGE_LAST_WRITE
                                                       | FILE_NOTIFY_CHANGE_SECURITY));
            },{
                handle = FindFirstChangeNotificationA(absolutePath.toLocal8Bit(),
                                                      false,
                                                      (FILE_NOTIFY_CHANGE_DIR_NAME
                                                       | FILE_NOTIFY_CHANGE_FILE_NAME
                                                       | FILE_NOTIFY_CHANGE_ATTRIBUTES
                                                       | FILE_NOTIFY_CHANGE_SIZE
                                                       | FILE_NOTIFY_CHANGE_LAST_WRITE
                                                       | FILE_NOTIFY_CHANGE_SECURITY));
            })
            if (handle == INVALID_HANDLE_VALUE)
Beispiel #3
0
int CALLBACK IniRepositoryWatcherThread(int)
{
  int result; // eax@8
  HANDLE v2; // eax@24
  DWORD v3; // eax@31
  DWORD v4; // eax@51
  char v5; // al@94
  char v6; // al@99
  char v7; // [sp+0h] [bp-2A0h]@7
  DWORD v8; // [sp+6Ch] [bp-234h]@69
  signed int v9; // [sp+70h] [bp-230h]@68
  unsigned int v10; // [sp+74h] [bp-22Ch]@15
  char Dst[268]; // [sp+78h] [bp-228h]@15
  HANDLE hChangeHandle; // [sp+184h] [bp-11Ch]@10
  HANDLE hHandle; // [sp+188h] [bp-118h]@9
  char v14[4]; // [sp+18Ch] [bp-114h]@33
  const CHAR Src; // [sp+190h] [bp-110h]@5
  unsigned int v16; // [sp+298h] [bp-8h]@1
  DWORD v17; // [sp+29Ch] [bp-4h]@33
  int v18; // [sp+2A0h] [bp+0h]@1

    if ( WndGetDevicesFolder((LPSTR)&Src, 0x104u, 0, 0) )
    {
        hHandle = g_pMain->hStopMainProcessThreadEvent;
        while(TRUE)
        {
            hChangeHandle = FindFirstChangeNotificationA(&Src, 1, 1u);
            if ( hChangeHandle == INVALID_HANDLE_VALUE )
            {
                strcpy_s(Dst, MAX_PATH, &Src);
                BYTE *pEnd = &Dst[strlen(Dst)];
                do
                {
                    while(*pEnd != '\\' && pEnd >= Dst)
                    {
                        --pEnd;
                    }
                    if(*pEnd != '\\')
                    {
                        return 0;
                    }
                    *pEnd = NULL;
                    hChangeHandle = FindFirstChangeNotificationA(Dst, 0, 2u);
                }
                while(hChangeHandle == INVALID_HANDLE_VALUE);
                if(hChangeHandle == INVALID_HANDLE_VALUE)
                {
                    return 0;
                }
                v17 = WaitForMultipleObjects(2u, &hChangeHandle, 0, 0xFFFFFFFFu);
                FindCloseChangeNotification(hChangeHandle);
                if ( !v17 )
                {
                    continue;
                }
                if ( v17 != 1 )
                {
                    continue;
                }
                result = 0;
            }
            else
            {
                if(hChangeHandle == INVALID_HANDLE_VALUE)
                {
                    result = 0;
                }
                else
                {
                    while ( 1 )
                    {
                        v17 = WaitForMultipleObjects(2u, &hChangeHandle, 0, 0xFFFFFFFFu);
                        if ( v17 )
                            break;
                        if ( !WaitForSingleObject(hHandle, 0x3E8u) )
                        {
                            break;
                        }
                        v9 = 1;
                        if(g_pMain->dwOndemandReloadStartTime)
                        {
                            OnDemandReloadElapsedTime = GetTickCount() - g_pMain->dwOndemandReloadStartTime;
                            if(OnDemandReloadElapsedTime < 5000)
                            {
                                v9 = 0;
                            }
                        }
                        if(v9)
                        {
                            MainAPIBroadcastControl(5, 0, 0, 0, 1);
                            if(IniLoadFilesFromPath((int *)&g_pMain->ModelTable, &g_pMain->ulModelCount, (void **)&g_pMain->field_1D1C, (int)&g_pMain->field_1D18, &Src, g_pGbl->dwFlags, 0))
                            {
                                if(!WaitForSingleObject(hHandle, 1000) )
                                    break;
                            }
                            MainAPIBroadcastControl(6, 0, 0, 0, 1);
                        }
                        if(!FindNextChangeNotification(hChangeHandle))
                        {
                            break;
                        }
                    }
                    FindCloseChangeNotification(hChangeHandle);
                    result = 0;
                }
            }
            break;
        }
    }
    else
    {
        result = 0;
    }
    return result;
}
Beispiel #4
0
	void run()
	{
		ItemInfoMap entries;
		scan(entries);
		
		DWORD filter = FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME;
		if (owner().eventMask() & DirectoryWatcher::DW_ITEM_MODIFIED)
			filter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
		
		std::string path(owner().directory().path());
#if defined(POCO_WIN32_UTF8)
		std::wstring upath;
		Poco::UnicodeConverter::toUTF16(path.c_str(), upath);
		HANDLE hChange = FindFirstChangeNotificationW(upath.c_str(), FALSE, filter);
#else
		HANDLE hChange = FindFirstChangeNotificationA(path.c_str(), FALSE, filter);
#endif

		if (hChange == INVALID_HANDLE_VALUE)
		{
			try
			{
				FileImpl::handleLastErrorImpl(path);
			}
			catch (Poco::Exception& exc)
			{
				owner().scanError(&owner(), exc);
			}
			return;
		}
		
		bool stopped = false;
		while (!stopped)
		{
			try
			{
				HANDLE h[2];
				h[0] = _hStopped;
				h[1] = hChange;
				switch (WaitForMultipleObjects(2, h, FALSE, INFINITE))
				{
				case WAIT_OBJECT_0:
					stopped = true;
					break;
				case WAIT_OBJECT_0 + 1:
					{
						ItemInfoMap newEntries;
						scan(newEntries);
						compare(entries, newEntries);
						std::swap(entries, newEntries);
						if (FindNextChangeNotification(hChange) == FALSE)
						{
							FileImpl::handleLastErrorImpl(path);
						}
					}
					break;
				default:
					throw SystemException("failed to wait for directory changes");
				}
			}
			catch (Poco::Exception& exc)
			{
				owner().scanError(&owner(), exc);
			}			
		}
		FindCloseChangeNotification(hChange);
	}
/**
 * @class kt::DirectoryWatcherService::Waiter
 */
void DirectoryWatcherService::Waiter::run() {
	// Prevent clients from running multiple directory watchers.
	// Which wouldn't be necessary if I'd put that handler into local data.
	std::lock_guard<std::mutex> lock(RUN_LOCK);
//	XXX Well... so actually, I can't print anything here or else the printing to the
//	command prompt is broken and nothing in the app prints at all. So yeah, now I really
//	want a logger that gets that print info to another thread.
//	VR_LOG_INFO("Start directory watcher");
//	DBG_LINE(std::cout << "Start directory watcher" << std::endl);
	DWORD				ans;
	HANDLE*				handle;
	DWORD				notify = FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME
								 | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE
								 | FILE_NOTIFY_CHANGE_LAST_WRITE;
	size_t				k, count = mPath.size();
	if (count < 1) return;
	// Insert my own handle I can wakeup
	++count;
	if ((handle = new HANDLE[count]) == 0) return;

	handle[0] = CreateEventW(0, FALSE, FALSE, 0);
	setWakeup(handle[0]);

	for (k = 1; k < count; k++) {
		handle[k] = FindFirstChangeNotificationA(mPath[k-1].c_str(), true, notify);
	}
	if (handle[0] == INVALID_HANDLE_VALUE) goto cleanup;
	for (k = 1; k < count; k++) {
		if (handle[k] == INVALID_HANDLE_VALUE) {
//			VR_LOG_INFO("ERROR DirectoryWatcherOp invalid handle on " << mPath[k-1]);
//			DBG_LINE(std::cout << "ERROR DirectoryWatcherOp invalid handle on " << mPath[k-1] << std::endl);
			goto cleanup;
		}
	}
//	VR_LOG_INFO("Start DirectoryWatcher loop");
//	DBG_LINE(std::cout << "Start DirectoryWatcher loop" << std::endl);
	while (TRUE) { 
		// Wait for notification.
		ans = WaitForMultipleObjectsEx(count, handle, FALSE, INFINITE, TRUE);

		if (isStopped()) goto cleanup;
		if (ans < WAIT_OBJECT_0 || ans >= WAIT_OBJECT_0 + count) goto cleanup;
		ans -= WAIT_OBJECT_0;

		if (ans >= 1 && ans < count) {
//			cout << "CHANGED=" << mPath[ans-1] << endl;
			if (!onChanged(mPath[ans-1])) goto cleanup;
		}

		if (FindNextChangeNotification(handle[ans]) == FALSE) goto cleanup;
	}

cleanup:
//	VR_LOG_INFO("End DirectoryWatcher");
//	DBG_LINE(std::cout << "End DirectoryWatcher" << std::endl);
	setWakeup(INVALID_HANDLE_VALUE);
	if (handle[0] != INVALID_HANDLE_VALUE) {
		CloseHandle(handle[0]);
	}
	for (k = 1; k < count; k++) {
		if (handle[k] != INVALID_HANDLE_VALUE)
			FindCloseChangeNotification(handle[k]);
	}
	delete[] handle;
}