Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: ReadDirectoryChangesW(): круговерть событий FILE_ACTION_MODIFIED  (Прочитано 6037 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
malor
Опытный

ru
Offline Offline

« : 06-04-2012 08:56 » 

Функция ReadDirectoryChangesW() запущена внутри потока. Следит за изменением файла somefile.dat внутри каталога.
В случае, если он был подвергнут модификации - делает отметку в лог-файле с указанием времени.

Код: (C++)
// Только строчку с временем пишем
void SomeAction()
{
    char sMsg[MAX_LENGHT_MSG] = "";  
    time_t t = time(NULL);
    struct tm * tm = localtime(&t);
    strcat(sMsg, asctime(tm));

    SaveLog(sMsg);
}

// Функция потока
DWORD WINAPI ThreadFunc(LPVOID lpParam)
{
    char sMsg[MAX_LENGHT_MSG] = "";  

    char buf[256 * (sizeof(FILE_NOTIFY_INFORMATION) + MAX_PATH * sizeof(WCHAR))] = {0};
    DWORD bytesReturned = 0;
    BOOL result = FALSE;
    FILE_NOTIFY_INFORMATION *fni = NULL;

    HANDLE hDir = CreateFile(pathDir,
        FILE_LIST_DIRECTORY | STANDARD_RIGHTS_READ,
        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
        NULL,
        OPEN_EXISTING,
        FILE_FLAG_BACKUP_SEMANTICS,
        NULL);
         
    if (!hDir || hDir == INVALID_HANDLE_VALUE)
    {
        wprintf(L"CreateFile failed\n");
        return 1;
    }

    while (1)
    {
        result = ReadDirectoryChangesW(hDir,
            buf,
            sizeof(buf) / 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);

        if (result && bytesReturned)
        {
            wchar_t filename[MAX_PATH];
            wchar_t action[256];
            for (fni = (FILE_NOTIFY_INFORMATION*)buf; fni; )
            {
                if (fni->FileNameLength)
                {
                    wcsncpy_s(filename, MAX_PATH, fni->FileName, fni->FileNameLength / 2);
                    filename[fni->FileNameLength / 2] = 0;
                    // События с другими файлами в директории не интересуют
                    if (wcsncmp(L"somefile.dat", filename, wcslen(filename)) != 0)
                    {
                        if (fni->NextEntryOffset)
                        {
                            char *p = (char*)fni;
                            fni = (FILE_NOTIFY_INFORMATION*)(p + fni->NextEntryOffset);
                        }
                        else
                        {
                            fni = NULL;
                        }                    
                        continue;
                    }

                }
                else
                {
                    //wprintf(L"%s <EMPTY>\n", action);
                }  

                switch (fni->Action)
                {

                case FILE_ACTION_MODIFIED:
                    strncat(sMsg, "File modified", 13);
                    SaveLog(sMsg);
                    SomeAction();      
                    break;

                default:
                    ;//swprintf_s(action, sizeof(action) / sizeof(*action), L"Unkonwn action: %ld. File name is:", fni->Action);
                }
               

                if (fni->NextEntryOffset)
                {
                    char *p = (char*)fni;
                    fni = (FILE_NOTIFY_INFORMATION*)(p + fni->NextEntryOffset);
                }
                else
                {
                    fni = NULL;
                }
            }
        }
        else
        {
            wprintf(L"ReadDirectoryChangesW failed\n");
        }
    }

    CloseHandle(hDir);
   
    return 0;
}

Сам лог:
Цитата
File modified
Fri Apr 06 12:19:25 2012

File modified
File modified
Fri Apr 06 12:19:25 2012

File modified
File modified
File modified
Fri Apr 06 12:19:38 2012

File modified
File modified
File modified
File modified
Fri Apr 06 12:19:38 2012

File modified
File modified
File modified
File modified
File modified
Fri Apr 06 12:19:41 2012

File modified
File modified
File modified
File modified
File modified
File modified
Fri Apr 06 12:19:41 2012

File modified
File modified
File modified
File modified
File modified
File modified
File modified
Fri Apr 06 12:19:44 2012

Почему столько записей вида "File modified"?
Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #1 : 06-04-2012 09:33 » new

попробуйте заменить strncat(sMsg, "File modified", 13); на strcpy(sMsg, "File modified")
Записан
malor
Опытный

ru
Offline Offline

« Ответ #2 : 06-04-2012 09:39 » 

Так и есть. Спасибо!
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines