Задать вопрос
@likilix
Лицемер

Кто поможет со ошибкой в ReadDirectoryChangesW?

#include <iostream>
#include <conio.h>

#include <vector>

using std::vector;
using std::cout;
using std::cin;
using std::endl;

#define pause() (_getch(),0)

#include <Windows.h>

DWORD dwFilterNotify = FILE_NOTIFY_CHANGE_FILE_NAME;
/*
						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; 
*/

int error()
{
 DWORD _error = ::GetLastError();
 cout<<"Error code: "<<_error<<endl;
 return _error;
}

const int size_fni = 100 * sizeof(FILE_NOTIFY_INFORMATION);

struct SDir 
{
 OVERLAPPED Over;
 BYTE *pBuffer;

 SDir() {
  pBuffer = new BYTE[size_fni + 1];
 }

~SDir() {
  delete []pBuffer;
 }
};

HANDLE CreateIoCompletionPort(DWORD dwNumberOfConcurrentThreads = 1) {
 return ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, dwNumberOfConcurrentThreads); 
}

BOOL AssignIoCompletionPort(HANDLE hDirectory, HANDLE hExistingCompletionPort, ULONG_PTR CompletionKey) {
 return 
	 (::CreateIoCompletionPort(hDirectory, hExistingCompletionPort, CompletionKey, 0) != NULL);
}

HANDLE AssignDirectory(LPTSTR lpDirectory) {
 return ::CreateFile(lpDirectory, FILE_LIST_DIRECTORY, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, 
	 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL);   
}

LPCSTR ExplainAction( DWORD dwAction )
{
	switch (dwAction)
	{
	case FILE_ACTION_ADDED            :
		return "Added";
	case FILE_ACTION_REMOVED          :
		return "Deleted";
	case FILE_ACTION_MODIFIED         :
		return "Modified";
	case FILE_ACTION_RENAMED_OLD_NAME :
		return "Renamed From";
	case FILE_ACTION_RENAMED_NEW_NAME :
		return "Renamed To";
	default:
		return "BAD DATA";
	}
}

DWORD __stdcall Thread(LPVOID lpParam)
{
	DWORD dwNumberOfBytesTransferred;
	
	HANDLE hDevice = nullptr;
	SDir* pDir = nullptr;

	DWORD dwBytesReturned = 0;

	for(;;)
	{
		BOOL _error = ::GetQueuedCompletionStatus(static_cast<HANDLE>(lpParam), &dwNumberOfBytesTransferred, (ULONG_PTR*)&hDevice, (OVERLAPPED**)&pDir, INFINITE);     

		if(!_error) {
			 error();
		}

			FILE_NOTIFY_INFORMATION *pBuffer = (FILE_NOTIFY_INFORMATION*)pDir->pBuffer;

					char*pChar = new char[pBuffer->FileNameLength / 2+1];

			WideCharToMultiByte( CP_ACP, 0, 
								 pBuffer->FileName, 
								 pBuffer->FileNameLength, 
								 pChar,
								 pBuffer->FileNameLength / 2, 
								 NULL, NULL);

			pChar[ pBuffer->FileNameLength / 2 ] = 0;

			cout<<pChar<<' '<<ExplainAction(pBuffer->Action)<<endl;

			delete pChar;

			/*

		*/

		memset((void*)&pDir->Over, 0, sizeof(OVERLAPPED));
		//memset((void*)pDir->pBuffer, 0, 100);

		

		_error = ::ReadDirectoryChangesW(
			hDevice, pDir->pBuffer, size_fni, FALSE, dwFilterNotify, &dwBytesReturned, &pDir->Over, 0 );   

		// parsing
		Sleep(1000);
		
	}

	return 0;
}

HANDLE CreateThread(HANDLE hIOCP)
{
 DWORD dwThreadId = 0;
 return ::CreateThread(NULL, 0, Thread, hIOCP, 0, &dwThreadId); 
}

int main()
{
	HANDLE hIOCP = CreateIoCompletionPort();

	DWORD dwBytesReturned = 0;

	SDir *pDir = new SDir;

	memset((void*)&pDir->Over, 0, sizeof(OVERLAPPED));

	if(!hIOCP) {
	  return error();
	}

	HANDLE hThread = CreateThread(hIOCP);

	if(!hThread) {
	  return error();
	}

	HANDLE hDirectory = nullptr;


	hDirectory = AssignDirectory(L"C:\\space\\1");

	if(!AssignIoCompletionPort(hDirectory, hIOCP, (ULONG_PTR)hDirectory))
	{
	 return error();	
	}

	BOOL _error = ::ReadDirectoryChangesW(
		hDirectory, pDir->pBuffer, size_fni, FALSE, dwFilterNotify, &dwBytesReturned, &pDir->Over, 0 );    

	if(!_error)
	{
	 return error();	
	}

	hDirectory = AssignDirectory(L"C:\\space\\2");

	if(!AssignIoCompletionPort(hDirectory, hIOCP, (ULONG_PTR)hDirectory))
	{
	 return error();	
	}

	//cout<< hDirectory << endl;

	_error = ::ReadDirectoryChangesW(
		hDirectory, pDir->pBuffer, size_fni, FALSE, dwFilterNotify, &dwBytesReturned, &pDir->Over, 0 );   

	
	WaitForSingleObject(hThread, INFINITE);



	return pause();
}


Проблема в следующем:
наблюдение я ввиду за директорией "C:\\space\\1"

1. Если я кидаю в нее файлы: 29-00014.IN, 29-00014.txt, 29-00015.IN, 29-00015.txt, то 1 или 2 файла не фиксируются функцией( не выводятся на консоль). С удалением тоже самое.
2. Иногда бывает когда я бросаю 4 файла в папу то вывод будет типа этого
"29-00014.txt" "29-00014.txt" "29-00014.txt" "29-00014.IN"

Вывод идет в Thread
  • Вопрос задан
  • 143 просмотра
Подписаться 1 Оценить Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы