Exemplo n.º 1
0
//===================================
void ConfigDestroy () {
    s_critsect.Enter();
    {
        for_each(s_dirMonitors.begin(), s_dirMonitors.end(), DestroyDirMonitor_CS());
        s_dirMonitors.clear();
    }
    s_critsect.Leave();

    // Wait until all directory monitors are deleted asynchronously
    while (s_dirCount)
        Sleep(1);
}
Exemplo n.º 2
0
//===================================
void DirMonitor::TaskComplete (
    unsigned        bytes,
    OVERLAPPED *
) {
    s_critsect.Enter();
    {
        if (m_handle == INVALID_HANDLE_VALUE) {
            // The monitor is ready to be deleted
        }
        // If no bytes read then m_buffer wasn't large enough to hold all the
        // updates; scan the directory to see which files need to be updated
        else if (!bytes) {
            ScanDirectoryForChanges_CS();
        }
        // Otherwise process the file notifications
        else for (const FILE_NOTIFY_INFORMATION * info = (const FILE_NOTIFY_INFORMATION *) m_buffer;;) {
            // Validate the structure
            // DebugMsg("  %u: %.*S\n", info->Action, info->FileNameLength / sizeof(info->FileName[0]), info->FileName);
            #ifdef ASSERTIONS_ENABLED
            size_t offset = (size_t) ((const byte *) info - (const byte *) m_buffer);
            ASSERT(offset < bytes);
            ASSERT(offset < sizeof_field(DirMonitor, m_buffer));
            #endif

            // Deleting or renaming a file does not cause re-parsing
            if ((info->Action == FILE_ACTION_REMOVED) || (info->Action == FILE_ACTION_RENAMED_OLD_NAME)) {
                // DebugMsg("%.*S deleted\n", info->FileNameLength / sizeof(info->FileName[0]), filename);
            }
            else {
                // Convert to lowercase for hash matching
                wchar filename[MAX_PATH];
                StrCopy(filename, min(_countof(filename), info->FileNameLength / sizeof(info->FileName[0]) + 1), info->FileName);
                CharLowerW(filename);

                // Reparse if file changed
                CheckReparseFile_CS(filename);
            }

            // Move to next entry
            if (!info->NextEntryOffset)
                break;
            info = (const FILE_NOTIFY_INFORMATION *) ((const byte *) info + info->NextEntryOffset);            
        }

        WatchDirectory_CS();
    }
    s_critsect.Leave();
}
Exemplo n.º 3
0
//===================================
void ConfigMonitorFile (const wchar filename[]) {
    // Convert to canonical lowercase form
    wchar fullpath[MAX_PATH];
    if (!GetFullPathNameW(filename, _countof(fullpath), fullpath, NULL)) {
        LOG_OS_LAST_ERROR(L"GetFullPathNameW");
        FatalError();
    }
    CharLowerW(fullpath);

    // Create the directory that contains the file to be watched
    wchar directory[MAX_PATH];
    PathRemoveFileName(directory, _countof(directory), fullpath);
    if (!PathCreateDirectory(directory))
        FatalError();

    // Get the filename part
    filename = PathFindFileNameW(fullpath);

    s_critsect.Enter();
    {
        // Create a monitor for this directory
        DirMonitor * dir = FindOrCreateDirectoryMonitor_CS(directory);

        // Does this file already exist in the monitor's file list?
        ConfigFile * file;
        ConfigFileMap::iterator pair = dir->m_files.find(filename);
        if (pair == dir->m_files.end()) {
            file = new ConfigFile(fullpath);
            dir->m_files.insert(ConfigFilePair(file->m_filename, file));
        }
        else {
            file = pair->second;
        }

        // TODO: signal file for reparsing so the callback gets called.
    }
    s_critsect.Leave();
}