1. ryanackley
  2. NPAPI-chrome-file-api

Source

NPAPI-chrome-file-api / Win / FileWatcherTaskWin.cpp

#include <string>
#include "FileWatcherTaskWin.h"
#include "variant_list.h"

void FileWatcherTaskWin::Watch(std::string p, FB::JSObjectPtr callback)
{
	boost::thread thread = boost::thread(boost::bind(&FileWatcherTaskWin::ListenForFileEvents, this, p, callback));
	thread.detach();
}

void FileWatcherTaskWin::ListenForFileEvents(std::string path, FB::JSObjectPtr callback)
{
	WCHAR widePathBuf[2048];
	int wpBufSize = MultiByteToWideChar(CP_UTF8, 0, path.c_str(), -1, widePathBuf, 2048);
	std::wstring widePath = widePathBuf;
	
	handle = CreateFile(widePath.c_str(), 
								FILE_LIST_DIRECTORY, 
								FILE_SHARE_READ | FILE_SHARE_WRITE,
								NULL,
								OPEN_EXISTING,
								FILE_FLAG_BACKUP_SEMANTICS,
								NULL);
								//FindFirstChangeNotification (widePath.c_str(), TRUE, FILE_NOTIFY_CHANGE_LAST_WRITE);
	
	
	while (handle != INVALID_HANDLE_VALUE && !this->ShouldStop())
	{
		char buffer[4096];
		DWORD bytesInBuf = 0;

		ReadDirectoryChangesW(handle, buffer, 4096, TRUE, FILE_NOTIFY_CHANGE_LAST_WRITE, &bytesInBuf, NULL, NULL);
		
		if (bytesInBuf > 0)
		{
			BOOL moreToRead = true;
			char* readFrom = buffer;
			while(moreToRead)
			{
				FILE_NOTIFY_INFORMATION* fni = (FILE_NOTIFY_INFORMATION*)readFrom;
				std::wstring fileName(fni->FileName, fni->FileNameLength/sizeof(WCHAR));
				std::wstring wideFinalPath = widePath + L"\\" + fileName;

				char utf8Buf[2048];
				int pathLength = WideCharToMultiByte(CP_UTF8, 0, wideFinalPath.c_str(), -1, utf8Buf, 2048, NULL, NULL);
				std::string finalPath = utf8Buf;
				
				callback->Invoke("", FB::variant_list_of(finalPath));
				if (!fni->NextEntryOffset)
				{
					moreToRead = false;
				}
				else
				{
					readFrom += fni->NextEntryOffset;
				}
			}
		}
	}
}

void FileWatcherTaskWin::StopWatching()
{
	BOOL success = CloseHandle(handle);
	this->stop = true;
}

bool FileWatcherTaskWin::ShouldStop()
{
	return stop;
}