BOOL CDirWatcher::StartWatch(HWND hNotifyWnd, LPCTSTR lpszPath)
{
	m_hNotifyWnd = hNotifyWnd;
	m_strPath = lpszPath;

	m_hFileHandle = CreateFile(m_strPath, 
		FILE_LIST_DIRECTORY,
		FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE,
		NULL,
		OPEN_EXISTING,
		FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED,
		NULL); 
	if (m_hFileHandle == INVALID_HANDLE_VALUE)
		return FALSE;

	m_hCompPort = CreateIoCompletionPort(m_hFileHandle, m_hCompPort, DWORD(this), 0);

	memset(&m_overlapped, 0, sizeof(OVERLAPPED));
	ReadDirectoryChangesW(m_hFileHandle, m_lpBuffer, 4096,
			FALSE, FILE_NOTIFY_CHANGE_FILE_NAME, &m_dwSize, &m_overlapped, NULL);
	
	m_hThread = CreateThread(NULL, 0, _WatchProc, (void*)this, 0, &m_dwThreadID);

	return TRUE;
}
Exemple #2
1
static BOOL
register_monitoring_entry(WDM_PEntry entry)
{
    BOOL success;
    DWORD bytes;
    bytes = 0; // Not used because the process callback gets passed the written bytes

    success = ReadDirectoryChangesW(
        entry->dir_handle,                  // handle to directory
        entry->buffer,                      // read results buffer
        WDM_BUFFER_SIZE,                    // length of buffer
        entry->user_data->watch_childeren,  // monitoring option
        entry->user_data->flags,            // filter conditions
        &bytes,                             // bytes returned
        &entry->event_container,            // overlapped buffer
        &handle_entry_change                // process callback
    );

    if ( ! success ) {
        WDM_DEBUG("ReadDirectoryChangesW failed with error (%d): %s", GetLastError(), rb_w32_strerror(GetLastError()));
        return FALSE;
    }

    return TRUE;
}
Exemple #3
1
void resman_check_watch(struct resman *rman)
{
    struct watch_dir *wdir;
    unsigned int idx;

    unsigned int num_handles = dynarr_size(rman->watch_handles);
    if(!num_handles) {
        return;
    }

    idx = WaitForMultipleObjectsEx(num_handles, rman->watch_handles, FALSE, 0, TRUE);
    if(idx == WAIT_FAILED) {
        unsigned int err = GetLastError();
        fprintf(stderr, "failed to check for file modification: %u\n", err);
        return;
    }
    if(idx >= WAIT_OBJECT_0 && idx < WAIT_OBJECT_0 + num_handles) {
        if(!(wdir = rb_find(rman->wdirbyev, rman->watch_handles[idx]))) {
            fprintf(stderr, "got change handle, but failed to find corresponding watch_dir!\n");
            return;
        }

        handle_event(rman, rman->watch_handles[idx], wdir);

        /* restart the watch call */
        ReadDirectoryChangesW(wdir->handle, wdir->buf, RES_BUF_SIZE, FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE, 0, &wdir->over, 0);
    }
}
Exemple #4
1
DWORD WINAPI FileSystemWatcher::Routine( LPVOID lParam )
{
    FileSystemWatcher* pFsw = (FileSystemWatcher*)lParam;
	CString tem1,tem2;
	CString str = (_T("[") + pFsw->WatchedDir + "] 开始监视!");
    pFsw->hDir = CreateFile(
        pFsw->WatchedDir,
        GENERIC_READ|GENERIC_WRITE,
        FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
        NULL,
        OPEN_EXISTING,
        FILE_FLAG_BACKUP_SEMANTICS,
        NULL
    );
    if( INVALID_HANDLE_VALUE == pFsw->hDir ) return false;

    char buf[ 2*(sizeof(FILE_NOTIFY_INFORMATION)+MAX_PATH) ];
    FILE_NOTIFY_INFORMATION* pNotify=(FILE_NOTIFY_INFORMATION *)buf;
    DWORD BytesReturned;
    while(true)
    {
        if( ReadDirectoryChangesW( pFsw->hDir,
            pNotify,
            sizeof(buf),
            true,
            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_LAST_ACCESS|
            FILE_NOTIFY_CHANGE_CREATION|
            FILE_NOTIFY_CHANGE_SECURITY,
            &BytesReturned,
            NULL,
            NULL ) )
        {
            char tmp[MAX_PATH], str1[MAX_PATH], str2[MAX_PATH];
            memset( tmp, 0, sizeof(tmp) );
            WideCharToMultiByte( CP_ACP,0,pNotify->FileName,pNotify->FileNameLength/2,tmp,99,NULL,NULL );
            strcpy_s( str1,260, tmp );

            if( 0 != pNotify->NextEntryOffset )
            {
                PFILE_NOTIFY_INFORMATION p = (PFILE_NOTIFY_INFORMATION)((char*)pNotify+pNotify->NextEntryOffset);
                memset( tmp, 0, sizeof(tmp) );
                WideCharToMultiByte( CP_ACP,0,p->FileName,p->FileNameLength/2,tmp,99,NULL,NULL );
                strcpy_s( str2,260, tmp );
            }
			tem1= str1;
			tem2= str2;
            pFsw->DealFunc((ACTION)pNotify->Action, tem1, tem2);
        } else
        {
            break;
        }
    }
    return 0;
}
void FileWatcher::Init(const WCHAR* fileFullPath)
{
    // if the thread already exists then stop it
    if (IsThreadRunning())
        SynchronousAbort();

    str::ReplacePtr(&filePath, fileFullPath);
    WCHAR *dirPath = path::GetDir(filePath);

    hDir = CreateFile(
        dirPath, // pointer to the directory containing the tex files
        FILE_LIST_DIRECTORY,                // access (read-write) mode
        FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE,  // share mode
        NULL, // security descriptor
        OPEN_EXISTING, // how to create
        FILE_FLAG_BACKUP_SEMANTICS  | FILE_FLAG_OVERLAPPED , // file attributes
        NULL); // file with attributes to copy
    free(dirPath);

    ZeroMemory(&overl, sizeof(overl));
    ZeroMemory(buffer, sizeof(buffer));
    overl.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

    // watch the directory
    ReadDirectoryChangesW(
         hDir, /* handle to directory */
         &buffer[curBuffer], /* read results buffer */
         sizeof(buffer[curBuffer]), /* length of buffer */
         FALSE, /* monitoring option */
         //FILE_NOTIFY_CHANGE_CREATION|
         FILE_NOTIFY_CHANGE_LAST_WRITE, /* filter conditions */
         NULL, /* bytes returned */
         &overl, /* overlapped buffer */
         NULL); /* completion routine */
}
void CDirectoryMonitor::WatchDirectoryInternal(ULONG_PTR dwParam)
{
	CDirInfo	*pDirInfo = NULL;

	pDirInfo = reinterpret_cast<CDirInfo *>(dwParam);

	if(pDirInfo->m_hDirectory == INVALID_HANDLE_VALUE)
	{
		free(pDirInfo->m_pData);

		return;
	}

	pDirInfo->m_FileNotifyBuffer = (FILE_NOTIFY_INFORMATION *)malloc(PRIMARY_BUFFER_SIZE);

	pDirInfo->m_bDirMonitored = ReadDirectoryChangesW(pDirInfo->m_hDirectory,
	pDirInfo->m_FileNotifyBuffer,PRIMARY_BUFFER_SIZE,
	pDirInfo->m_bWatchSubTree,pDirInfo->m_WatchFlags,NULL,&pDirInfo->m_Async,
	CompletionRoutine);

	if(!pDirInfo->m_bDirMonitored)
	{
		free(pDirInfo->m_FileNotifyBuffer);
		CancelIo(pDirInfo->m_hDirectory);
		CloseHandle(pDirInfo->m_hDirectory);
	}
}
Exemple #7
0
void gep::DirectoryWatcher::doRead()
{
    memset(&m_overlapped, 0, sizeof(m_overlapped));
    ReadDirectoryChangesW(m_directoryHandle, m_buffer, GEP_ARRAY_SIZE(m_buffer),
        (m_watchSubdirs == WatchSubdirs::yes),
        m_filter, nullptr, &m_overlapped, nullptr);
}
//-----------------------------------------------------------------------------
static void start_watch(struct watch_entry * watch_entry_p) {
//-----------------------------------------------------------------------------
    BOOL start_read_result;

    memset(&watch_entry_p->overlap, 0, sizeof(watch_entry_p->overlap));	

    // start an overlapped 'read' to look for a filesystem change
    start_read_result = ReadDirectoryChangesW(
        watch_entry_p->hDirectory,
        watch_entry_p->changes_buffer,
        CHANGES_BUFFER_SIZE,
        TRUE,
        DIRECTORY_CHANGES_FILTER,
        NULL,
        (LPOVERLAPPED) watch_entry_p,
        NULL
    );

    if (!start_read_result) {
		DWORD err = GetLastError();
        report_error(L"ReadDirectoryChangesW", err);
		/* This error is reported for a handle to a file, meaning a folder has been
			recreated as a file after it was selected for backup.
		*/
		if (err != ERROR_INVALID_PARAMETER)
			ExitProcess(10);
    }

} // start_watch
void
sbWin32FileSystemWatcher::WatchNextChange()
{
  TRACE("%s", __FUNCTION__);
  DWORD const flags =
    FILE_NOTIFY_CHANGE_FILE_NAME |
    FILE_NOTIFY_CHANGE_DIR_NAME |
    FILE_NOTIFY_CHANGE_LAST_WRITE |
    FILE_NOTIFY_CHANGE_CREATION;

  if (mRootDirHandle != INVALID_HANDLE_VALUE) {
    BOOL result =
      ReadDirectoryChangesW(mRootDirHandle,
                            mBuffer,
                            BUFFER_LEN,
                            TRUE,  // watch subdirs
                            flags,
                            NULL,
                            &mOverlapped,
                            ReadDirectoryChangesWCallbackRoutine);
    if (!result) {
      NS_WARNING("ERROR: Could not ReadDirectoryChangesW()");
      if (mRootDirHandle != INVALID_HANDLE_VALUE) {
        CloseHandle(mRootDirHandle);
        mRootDirHandle = INVALID_HANDLE_VALUE;
      }
    }
  }
}
static unsigned int __stdcall
tr_watchdir_win32_thread (void * context)
{
  const tr_watchdir_t handle = context;
  tr_watchdir_win32 * const backend = BACKEND_UPCAST (tr_watchdir_get_backend (handle));
  DWORD bytes_transferred;

  while (tr_get_overlapped_result_ex (backend->fd, &backend->overlapped, &bytes_transferred,
                                      INFINITE, FALSE))
    {
      PFILE_NOTIFY_INFORMATION info = (PFILE_NOTIFY_INFORMATION) backend->buffer;

      while (info->NextEntryOffset != 0)
        *((BYTE **) &info) += info->NextEntryOffset;

      info->NextEntryOffset = bytes_transferred - ((BYTE *) info - (BYTE *) backend->buffer);

      send (backend->notify_pipe[1], (const char *) backend->buffer, bytes_transferred, 0);

      if (!ReadDirectoryChangesW (backend->fd, backend->buffer, sizeof (backend->buffer), FALSE,
                                  WIN32_WATCH_MASK, NULL, &backend->overlapped, NULL))
        {
          log_error ("Failed to read directory changes");
          return 0;
        }
    }

  if (GetLastError () != ERROR_OPERATION_ABORTED)
    log_error ("Failed to wait for directory changes");

  return 0;
}
static int beginMonitor(VPLFS_MonitorHandle_t* handle)
{
    // VPL_REPORT_INFO("beginMonitor called");
    int rv = 0;
    handle->overlapped.Internal = 0;
    handle->overlapped.InternalHigh = 0;
    handle->overlapped.Offset = 0;
    handle->overlapped.OffsetHigh = 0;
    handle->overlapped.hEvent = handle;  // hEvent not used by system, used as ctx ptr.
#ifdef VPL_PLAT_IS_WINRT
    // TODO: using WinRT APIs to implement file monitor
    rv = VPL_ERR_NOOP;
#else
    if(!ReadDirectoryChangesW(handle->hDir,
                              handle->pBuffer, //<--FILE_NOTIFY_INFORMATION records are put into this buffer
                              handle->nBufferLength,
                              TRUE,
                              FILE_NOTIFY_CHANGE_FILE_NAME|
                                  FILE_NOTIFY_CHANGE_DIR_NAME|
                                  FILE_NOTIFY_CHANGE_SIZE|
                                  FILE_NOTIFY_CHANGE_LAST_WRITE|
                                  FILE_NOTIFY_CHANGE_CREATION,
                              NULL, // Only defined for synchronous calls.
                              &handle->overlapped,
                              &ChDirCompletionRoutine) )
    {
       rv = VPLError_GetLastWinError();
    }
#endif
    return rv;
}
Exemple #12
0
static WatchedDir *NewWatchedDir(const WCHAR *dirPath)
{
    WatchedDir *wd = AllocStruct<WatchedDir>();
    wd->dirPath = str::Dup(dirPath);
    wd->hDir = CreateFile(
        dirPath, FILE_LIST_DIRECTORY,
        FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE,
        NULL, OPEN_EXISTING,
        FILE_FLAG_BACKUP_SEMANTICS  | FILE_FLAG_OVERLAPPED, NULL);
    if (!wd->hDir)
        goto Failed;

    wd->overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (!wd->overlapped.hEvent)
        goto Failed;

    // start watching the directory
    wd->currBuffer = 0;
    ReadDirectoryChangesW(
         wd->hDir,
         &wd->buffer[wd->currBuffer], /* read results buffer */
         sizeof(wd->buffer[wd->currBuffer]), /* length of buffer */
         FALSE, /* monitoring option */
         FILE_NOTIFY_CHANGE_LAST_WRITE, /* filter conditions */
         NULL, /* bytes returned */
         &wd->overlapped, /* overlapped buffer */
         NULL); /* completion routine */

    return wd;
Failed:
    FreeWatchedDir(wd);
    return NULL;
}
static void uv_fs_event_queue_readdirchanges(uv_loop_t* loop,
    uv_fs_event_t* handle) {
  assert(handle->dir_handle != INVALID_HANDLE_VALUE);
  assert(!handle->req_pending);

  memset(&(handle->req.u.io.overlapped), 0,
         sizeof(handle->req.u.io.overlapped));
  if (!ReadDirectoryChangesW(handle->dir_handle,
                             handle->buffer,
                             uv_directory_watcher_buffer_size,
                             (handle->flags & UV_FS_EVENT_RECURSIVE) ? TRUE : FALSE,
                             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_LAST_ACCESS  |
                               FILE_NOTIFY_CHANGE_CREATION     |
                               FILE_NOTIFY_CHANGE_SECURITY,
                             NULL,
                             &handle->req.u.io.overlapped,
                             NULL)) {
    /* Make this req pending reporting an error. */
    SET_REQ_ERROR(&handle->req, GetLastError());
    uv_insert_pending_req(loop, (uv_req_t*)&handle->req);
  }

  handle->req_pending = 1;
}
int FileSystemWatcherTask::task()
{
	m_handle = CreateFile(m_path,
		FILE_LIST_DIRECTORY,
		FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
		nullptr,
		OPEN_EXISTING,
		FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
		nullptr);
	if (m_handle == INVALID_HANDLE_VALUE) return -1;

	Lumix::setMemory(&m_overlapped, 0, sizeof(m_overlapped));
	m_overlapped.hEvent = this;
	m_finished = false;
	while (!m_finished)
	{
		PROFILE_BLOCK("Change handling");
		BOOL status = ReadDirectoryChangesW(m_handle,
			m_info,
			sizeof(m_info),
			TRUE,
			READ_DIR_CHANGE_FILTER,
			&m_received,
			&m_overlapped,
			&notif);
		if (status == FALSE) break;
		SleepEx(INFINITE, TRUE);
	}
	return 0;
}
Exemple #15
0
VOID CFileMonitorRequest::CheckFileChange()
{
    DWORD dwBytes = 0;
    if ( FALSE == ReadDirectoryChangesW( m_hMonitorPath , &m_vecShareMem[0] , (DWORD)m_vecShareMem.size() , m_bRecursive , m_dwFilter , 
        &dwBytes , &m_overlapped , CFileMonitorRequest::OnChangeComplete ) )
    {
        CWUtils::ShowDebugMsg();
    }
}
bool FileMon::monitor(const std::string &path) {
#ifdef WIN32
#ifdef UNICODE
  wchar_t path2[512];
  MultiByteToWideChar(CP_ACP,0,path.c_str(),-1,path2,512);
#else
  const char *path2=path.c_str();
#endif

  WatchStruct* pWatch;
  size_t ptrsize = sizeof(*pWatch);
  pWatch = static_cast<WatchStruct*>(HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,ptrsize));

  pWatch->mDirHandle = CreateFile(path2,FILE_LIST_DIRECTORY,
    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,NULL,
    OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,NULL);

  pWatch->fileMon=this;

  if(pWatch->mDirHandle != INVALID_HANDLE_VALUE) {
    pWatch->mOverlapped.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
    pWatch->mNotifyFilter = FILE_NOTIFY_CHANGE_CREATION|FILE_NOTIFY_CHANGE_LAST_WRITE|FILE_NOTIFY_CHANGE_FILE_NAME;

    if(ReadDirectoryChangesW(
      pWatch->mDirHandle,pWatch->mBuffer,sizeof(pWatch->mBuffer),FALSE,
      pWatch->mNotifyFilter,NULL,&pWatch->mOverlapped,WatchCallback) != 0) {
      pWatch->mDirName=path;
      mWatches.insert(std::make_pair(path,pWatch));
      return true;
    } else {
      CloseHandle(pWatch->mOverlapped.hEvent);
      CloseHandle(pWatch->mDirHandle);
    }
  }

  HeapFree(GetProcessHeap(),0,pWatch);
  return false;
#endif

#ifdef LINUX
  int watch = inotify_add_watch(notify,path.c_str(),IN_CLOSE_WRITE | IN_MOVED_TO | IN_CREATE | IN_MOVED_FROM | IN_DELETE);

  if(watch < 0) {
    if(errno == ENOENT) {
      std::cout << "File monitor: File/dir not found error.\n";
      return false;
    } else {
      std::cout << "File monitor: " << strerror(errno) << std::endl;;
      return false;
    }
  } else {
    watchMap[watch]=path;
  }
  return true;
#endif
}
Exemple #17
0
static int refresh_dirmonitor(FileMonitor *fm, int is_clear)
{
    enum {
        NOTIFY_FILTER = FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE,
    };

    return ReadDirectoryChangesW(
        fm->hDir, fm->buffer, sizeof(fm->buffer), FALSE,
        NOTIFY_FILTER, NULL, &fm->overlapped, is_clear ? NULL : file_monitor_callback) != 0;
}
Exemple #18
0
//Register a watch to receive events
void register_watch(WatchData &watch){
	std::memset(&watch.info_buf[0], 0, watch.info_buf.size());
	bool status = ReadDirectoryChangesW(watch.dir_handle, &watch.info_buf[0],
		watch.info_buf.size(), false, remap_file_notify(watch.filter), nullptr,
		&watch.overlapped, watch_callback);
	if (!status){
		std::cerr << "lfw Error: could not register watch on " << watch.dir_name
			<< ": " << get_error_msg(GetLastError()) << std::endl;
	}
}
Exemple #19
0
BOOL STDCALL OSFileHasChanged (OSFileChangeData *data)
{
    BOOL hasModified = FALSE;

    if(HasOverlappedIoCompleted(&data->directoryChange))
    {
        FILE_NOTIFY_INFORMATION *notify = (FILE_NOTIFY_INFORMATION*)data->changeBuffer;

        for (;;)
        {
            if (notify->Action != FILE_ACTION_RENAMED_OLD_NAME && notify->Action != FILE_ACTION_REMOVED)
            {
                String strFileName;
                strFileName.SetLength(notify->FileNameLength);
                scpy_n(strFileName, notify->FileName, notify->FileNameLength/2);
                strFileName.KillSpaces();

                String strFileChanged;
                strFileChanged << data->strDirectory << strFileName;             

                if(strFileChanged.CompareI(data->targetFileName))
                {
                    hasModified = TRUE;
                    break;
                }
            }

            if (!notify->NextEntryOffset)
                break;

            notify = (FILE_NOTIFY_INFORMATION*)((BYTE *)notify + notify->NextEntryOffset);
        }

        CloseHandle (data->directoryChange.hEvent);

        DWORD test;
        zero(&data->directoryChange, sizeof(data->directoryChange));
        zero(data->changeBuffer, sizeof(data->changeBuffer));

        data->directoryChange.hEvent = CreateEvent (NULL, TRUE, FALSE, NULL);

        if(ReadDirectoryChangesW(data->hDirectory, data->changeBuffer, 2048, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE, &test, &data->directoryChange, NULL))
        {
        }
        else
        {
            CloseHandle(data->directoryChange.hEvent);
            CloseHandle(data->hDirectory);
            return hasModified;
        }
    }

    return hasModified;
}
/// Refreshes the directory monitoring.
bool RefreshWatch(WatchStruct* pWatch, bool _clear)
{
  return ReadDirectoryChangesW(
    pWatch->mDirHandle,
    pWatch->mBuffer,
    sizeof(pWatch->mBuffer),
    pWatch->mRecursive,
    pWatch->mNotifyFilter,
    NULL,
    &pWatch->mOverlapped,
    _clear ? 0 : WatchCallback) != 0;
}
Exemple #21
0
bool C4FileMonitor::Execute(int iTimeout, pollfd *)
{
	// Check event
	if (WaitForSingleObject(hEvent, iTimeout) != WAIT_OBJECT_0)
		return true;
	// Check handles
	for (TreeWatch *pWatch = pWatches; pWatch; pWatch = pWatch->Next)
	{
		DWORD dwBytes = 0;
		// Has a notification?
		if (GetOverlappedResult(pWatch->hDir, &pWatch->ov, &dwBytes, false))
		{
			// Read notifications
			const char *pPos = pWatch->Buffer;
			for (;;)
			{
				const _FILE_NOTIFY_INFORMATION *pNotify = reinterpret_cast<const _FILE_NOTIFY_INFORMATION *>(pPos);
				// Handle
				HandleNotify(pWatch->DirName.getData(), pNotify);
				// Get next entry
				if (!pNotify->NextEntryOffset) break;
				pPos += pNotify->NextEntryOffset;
				if (pPos >= pWatch->Buffer + Min<size_t>(sizeof(pWatch->Buffer), dwBytes))
					break;
				break;
			}
			// Restart directory change notification (flush queue)
			ReadDirectoryChangesW(pWatch->hDir, pWatch->Buffer, sizeof(pWatch->Buffer), false, C4FileMonitorNotifies, NULL, &pWatch->ov, NULL);
			dwBytes = 0;
			while (GetOverlappedResult(pWatch->hDir, &pWatch->ov, &dwBytes, false))
			{
				ReadDirectoryChangesW(pWatch->hDir, pWatch->Buffer, sizeof(pWatch->Buffer), false, C4FileMonitorNotifies, NULL, &pWatch->ov, NULL);
				dwBytes = 0;
			}
		}
	}
	ResetEvent(hEvent);
	return true;
}
	static void CALLBACK callback(DWORD errorCode,
								  DWORD tferred,
								  LPOVERLAPPED over)
	{
		if (errorCode > 0)
		{
			return;
		}
		FileSystemWatcherPC* watcher = (FileSystemWatcherPC*)over->hEvent;
		if (tferred > 0)
		{
			FILE_NOTIFY_INFORMATION* info = &watcher->m_info[0];
			while (info)
			{
				switch (info->Action)
				{
					case FILE_ACTION_RENAMED_NEW_NAME:
					case FILE_ACTION_ADDED:
					case FILE_ACTION_MODIFIED:
					{
						char tmp[MAX_PATH];
						wcharToCharArray(
							info->FileName, tmp, info->FileNameLength);
						watcher->m_callback.invoke(tmp);
						//								watcher->m_asset_browser->emitFileChanged(tmp);
					}
					break;
					case FILE_ACTION_RENAMED_OLD_NAME:
					case FILE_ACTION_REMOVED:
						// do not do anything
						break;
					default:
						ASSERT(false);
						break;
				}
				info = info->NextEntryOffset == 0
						   ? nullptr
						   : (FILE_NOTIFY_INFORMATION*)(((char*)info) +
														info->NextEntryOffset);
			}
		}
		BOOL b = ReadDirectoryChangesW(watcher->m_handle,
									   watcher->m_info,
									   sizeof(watcher->m_info),
									   TRUE,
									   READ_DIR_CHANGE_FILTER,
									   &watcher->m_received,
									   &watcher->m_overlapped,
									   callback);
		ASSERT(b);
	}
FileMon::~FileMon() {
#ifdef WIN32
  for(auto i : mWatches) {
    WatchStruct* pWatch=i.second;

    DWORD dwWaitResult = WaitForSingleObject(ghMutex,INFINITE);

    while(true) {
      if(dwWaitResult==WAIT_OBJECT_0) {
        pWatch->mStopNow = TRUE;

        if(!ReleaseMutex(ghMutex)) {
          std::cout << "FileMon : Release mutex err.\n";
        }

        break;
      } else if(dwWaitResult==WAIT_ABANDONED) {
        break;
      }
    }

    CancelIo(pWatch->mDirHandle);

    ReadDirectoryChangesW(
      pWatch->mDirHandle,pWatch->mBuffer,sizeof(pWatch->mBuffer),FALSE,
      pWatch->mNotifyFilter,NULL,&pWatch->mOverlapped,0);

    if(!HasOverlappedIoCompleted(&pWatch->mOverlapped)) {
      SleepEx(5,TRUE);
    }

    CloseHandle(pWatch->mOverlapped.hEvent);
    CloseHandle(pWatch->mDirHandle);
    HeapFree(GetProcessHeap(),0,pWatch);
  }

  CloseHandle(ghMutex);
#endif

#ifdef LINUX
  if(notify) {
    for(auto i : watchMap) {
      inotify_rm_watch(notify,i.first); //unnecessary because of close below?
    }
  }

  if(notify) {
    close(notify);
  }
#endif
}
Exemple #24
0
unsigned int CFileWatcher::Worker(void* arg)
{
	CFileWatcher* watcher = (CFileWatcher*)arg;
	DWORD error;
	DWORD bytes;
	ULONG_PTR key;
	LPOVERLAPPED overlapped;

	while (TRUE)
	{
		error = S_OK;
		if (!GetQueuedCompletionStatus(
			watcher->completionPort, &bytes, &key, &overlapped, watcher->uncFileSharePollingInterval))
		{
			error = GetLastError();
		}

		if (-1L == key) // terminate thread
		{
			break;
		}
		else if (S_OK == error) // a change in registered directory detected (local file system)
		{
			WatchedDirectory* directory = (WatchedDirectory*)key;
			
			watcher->ScanDirectory(directory, FALSE);

			RtlZeroMemory(&directory->overlapped, sizeof directory->overlapped);
			ReadDirectoryChangesW(
				directory->watchHandle,
				&directory->info,
				sizeof directory->info,
				FALSE,
				FILE_NOTIFY_CHANGE_LAST_WRITE,
				NULL,
				&directory->overlapped,
				NULL);
		}
		else // timeout - scan all registered UNC files for changes
		{
			WatchedDirectory* current = watcher->directories;
			while (current)
			{
				watcher->ScanDirectory(current, TRUE);
				current = current->next;
			}
		}		
	}

	return 0;
}
bool CCheckDirChange::WatchDirChanges(PReadDirChangeInfo pChangeInfo)
{
	pChangeInfo->pFileNotification = (FILE_NOTIFY_INFORMATION*)(new char[pChangeInfo->dwMaxBufferLen]);
	memset(pChangeInfo->pFileNotification,0,pChangeInfo->dwMaxBufferLen);

	return ReadDirectoryChangesW(m_hDirectory,
		pChangeInfo->pFileNotification,
		pChangeInfo->dwMaxBufferLen,
		TRUE,
		FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_LAST_WRITE|FILE_NOTIFY_CHANGE_DIR_NAME, 
		&pChangeInfo->dwReturnLen,
		&pChangeInfo->overlapped,
		NULL)?true:false;
}
void FileSystem::ListenForDirectoryChanges(std::string directory)
{
	HANDLE h_Directory = ::CreateFile(
		directory.c_str(),					// pointer to the file name
		FILE_LIST_DIRECTORY,                // access (read/write) mode
		FILE_SHARE_READ						// share mode
		 | FILE_SHARE_WRITE
		 | FILE_SHARE_DELETE,
		NULL,                               // security descriptor
		OPEN_EXISTING,                      // how to create
		FILE_FLAG_BACKUP_SEMANTICS			// file attributes
		 | FILE_FLAG_OVERLAPPED,
		NULL);                              // file with attributes to copy

	if (h_Directory == INVALID_HANDLE_VALUE)
	{
		std::cout << "ERROR: Error opening directory to watch: " << directory << std::endl;
	}

	int nCounter = 0;
    FILE_NOTIFY_INFORMATION strFileNotifyInfo[1024];
    DWORD dwBytesReturned = 0;   

    while(TRUE)
    {
        int count = 0;

		if( ReadDirectoryChangesW ( h_Directory, (LPVOID)&strFileNotifyInfo, sizeof(strFileNotifyInfo), TRUE, FILE_NOTIFY_CHANGE_LAST_WRITE, &dwBytesReturned, NULL, NULL) == 0)
        {
        }
        else
        {
			wchar_t filename[MAX_PATH];
			if (strFileNotifyInfo[0].FileNameLength)
            {
                wcsncpy_s(filename, MAX_PATH, strFileNotifyInfo[0].FileName, strFileNotifyInfo[0].FileNameLength / 2);
                filename[strFileNotifyInfo[0].FileNameLength / 2] = 0;
                
				std::wstring ws( filename );
				std::string convert_str( ws.begin(), ws.end());
				std::replace(convert_str.begin(), convert_str.end(), '\\', '/' );
				for(std::vector<void (*)(std::string modified_file)>::iterator it = _change_listeners.begin(); it != _change_listeners.end(); ++it) {
					(*it)(directory + "/" + convert_str);
				}
				
            }
        }
		boost::this_thread::sleep(boost::posix_time::milliseconds(2000));
    }
}
Exemple #27
0
OSFileChangeData * STDCALL OSMonitorFileStart(String path, bool suppressLogging)
{
    HANDLE hDirectory;
    OSFileChangeData *data = (OSFileChangeData *)Allocate(sizeof(*data));

    String strDirectory = path;
    strDirectory.FindReplace(TEXT("\\"), TEXT("/"));
    strDirectory = GetPathDirectory(strDirectory);
    strDirectory.FindReplace(TEXT("/"), TEXT("\\"));
    strDirectory << TEXT("\\");

    scpy_n (data->strDirectory, strDirectory.Array(), _countof(data->strDirectory)-1);

    hDirectory = CreateFile(data->strDirectory, FILE_LIST_DIRECTORY, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED, NULL);
    if(hDirectory != INVALID_HANDLE_VALUE)
    {
        DWORD test;
        zero(&data->directoryChange, sizeof(data->directoryChange));
        
        data->directoryChange.hEvent = CreateEvent (NULL, TRUE, FALSE, NULL);

        if(ReadDirectoryChangesW(hDirectory, data->changeBuffer, 2048, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE, &test, &data->directoryChange, NULL))
        {
            scpy_n (data->targetFileName, path.Array(), _countof(data->targetFileName)-1);
            data->hDirectory = hDirectory;
            return data;
        }
        else
        {
            int err = GetLastError();
            CloseHandle(data->directoryChange.hEvent);
            CloseHandle(hDirectory);
            if(!suppressLogging)
                Log(TEXT("OSMonitorFileStart: Unable to monitor file '%s', error %d"), path.Array(), err);
            Free(data);
            return NULL;
        }
    }
    else
    {
        if(!suppressLogging)
        {
            int err = GetLastError();
            Log(TEXT("OSMonitorFileStart: Unable to open directory '%s', error %d"), data->strDirectory, err);
        }
        Free(data);
        return NULL;
    }
}
    void DirectoryWatcherImpl::watch()
    {
        m_fileHandle = CreateFileA(m_directory.c_str(), FILE_LIST_DIRECTORY, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
            
        if (m_fileHandle == INVALID_HANDLE_VALUE)
        {
            JOP_DEBUG_ERROR("Failed to start directory watcher, directory: " << m_directory);
            m_active = false;
            m_error = true;
            m_fileHandle = nullptr;
            return;
        }
    
        FILE_NOTIFY_INFORMATION fileNotifyInfo[4];
        DWORD bytesReturned = sizeof(FILE_NOTIFY_INFORMATION);
    
        while (!m_shouldClose)
        {
            while (!m_active)
            {
                std::this_thread::sleep_for(std::chrono::seconds(1));
                continue;
            }
    
            if (ReadDirectoryChangesW(m_fileHandle,
                &fileNotifyInfo,
                sizeof(fileNotifyInfo),
                TRUE,
                FILE_NOTIFY_CHANGE_LAST_WRITE,
                &bytesReturned,
                NULL,
                NULL))
            {
                if (fileNotifyInfo[0].Action == FILE_ACTION_MODIFIED)
                {
                    DirectoryWatcher::Info info;
    
                    info.filename = std::wstring_convert<std::codecvt_utf8<wchar_t>>().to_bytes(std::wstring(fileNotifyInfo[0].FileName, fileNotifyInfo[0].FileNameLength / sizeof(wchar_t)));
    
                    if (!(info == m_lastEvent))
                    {
                        m_lastEvent = info;

                        m_callback(m_lastEvent);
                    }
                }
            }
        }
    }
Exemple #29
0
void MonitorDirectory(HANDLE hDir,LPTSTR lpServer)
{

	time_t rawtime;


	TCHAR szBuffer[640] = {0};	
	DWORD dwOffset = 0;
	FILE_NOTIFY_INFORMATION* pInfo = NULL;
	DWORD dwbytes =0;
	
	BOOL retval;

	//synchronous (blocking) function. Will return when a monitored change has occured
	retval = ReadDirectoryChangesW(hDir,
						  szBuffer,
						  sizeof(szBuffer)/sizeof(TCHAR),
						  FALSE,
						  FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_SIZE,
						  &dwbytes,
						  NULL,
						  NULL);

	if (0 == retval)
	{
		printf("\n ERROR: ReadDirectoryChanges function failed. \n");
		return;
	}

	do
	{
	  pInfo = (FILE_NOTIFY_INFORMATION*) &szBuffer[dwOffset];
	  TCHAR szFileName[MAX_PATH] = {0};
	  WideCharToMultiByte(CP_ACP,NULL,pInfo->FileName,pInfo->FileNameLength,szFileName,sizeof(szFileName)/sizeof(TCHAR),NULL,NULL);

	  
	  if(FILE_ACTION_ADDED == pInfo->Action || FILE_ACTION_MODIFIED == pInfo->Action)
	  {
		time(&rawtime);
	  
	  _tprintf(TEXT("Filename (%s) changed at time %s.\n"), szFileName, ctime(&rawtime));
		TransferFile(szFileName,lpServer);
	  }

	  dwOffset += pInfo->NextEntryOffset;		
	} while (pInfo->NextEntryOffset != 0);


}
static GObject *
g_win32_directory_monitor_constructor (GType                  type,
				       guint                  n_construct_properties,
				       GObjectConstructParam *construct_properties) {
  GObject *obj;
  GWin32DirectoryMonitorClass *klass;
  GObjectClass *parent_class;
  GWin32DirectoryMonitor *self;
  wchar_t *wdirname;
  gboolean result;

  klass = G_WIN32_DIRECTORY_MONITOR_CLASS (g_type_class_peek (G_TYPE_WIN32_DIRECTORY_MONITOR));
  parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
  obj = parent_class->constructor (type, n_construct_properties, construct_properties);
  self = G_WIN32_DIRECTORY_MONITOR (obj);
  wdirname = g_utf8_to_utf16 (G_LOCAL_DIRECTORY_MONITOR (obj)->dirname, -1, NULL, NULL, NULL);

  self->priv->hDirectory = CreateFileW (wdirname,
					FILE_LIST_DIRECTORY,
					FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 

					NULL,
					OPEN_EXISTING,
					FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
					NULL); 
  g_free (wdirname);
  if (self->priv->hDirectory == INVALID_HANDLE_VALUE)
    {
      /* Ignore errors */
      return obj;
    }

  result = ReadDirectoryChangesW (self->priv->hDirectory,
				  (gpointer)self->priv->file_notify_buffer,
				  self->priv->buffer_allocated_bytes,
				  FALSE, 
				  FILE_NOTIFY_CHANGE_FILE_NAME |
				  FILE_NOTIFY_CHANGE_DIR_NAME |
				  FILE_NOTIFY_CHANGE_ATTRIBUTES |
				  FILE_NOTIFY_CHANGE_SIZE,
				  &self->priv->buffer_filled_bytes,
				  &self->priv->overlapped,
				  g_win32_directory_monitor_callback);
  /* Ignore errors */

  return obj;
}