Как копировать точку повторной обработки или удалить reparse point
При удалении reparse данных из файла у него пропадает атрибут FILE_ATTRIBUTE_REPARSE_POINT и он перестаёт быть точкой повторной обработки. Файл или каталог становится обратно обычным объектом файловой системы.
О создании ссылок читайте статью Создание символьной ссылки Windows на C/C++.
Удаление reparse
Удаление данных точки повторной обработки выполняется через вызов DeviceIoControl с параметром FSCTL_DELETE_REPARSE_POINT. Перед вызовом DeviceIoControl требуется узнать значение ReparseTag, то есть тип точки повторной обработки. Этот тип тоже указывается при вызове функции.
Чтобы получить ReparseTag нужно вызвать DeviceIoControl с параметром FSCTL_GET_REPARSE_POINT, и вынуть его из структуры REPARSE_DATA_BUFFER или REPARSE_GUID_DATA_BUFFER (неважно, так как поле ReparseTag в них находится по одному смещению).
HANDLE OpenLinkHandle(LPCTSTR pszPath) { return CreateFile(pszPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL); } DWORD GetReparseDataTag(LPCTSTR src) { char reparse_buf[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; PREPARSE_DATA_BUFFER rd = (PREPARSE_DATA_BUFFER) reparse_buf; DWORD dwRet; HANDLE hSrc; // Открыть и получить reparse-данные из первого файла или каталога hSrc = OpenLinkHandle(src); if (hSrc == INVALID_HANDLE_VALUE) { return FALSE; } if (!DeviceIoControl(hSrc, FSCTL_GET_REPARSE_POINT, NULL, 0, rd, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &dwRet, NULL)) { return FALSE; } CloseHandle(hSrc); return rd->ReparseTag; }
После того, как с помощью функции GetReparseDataTag получен тег, означающий тип точки повторной обработки, можно удалить из файла reparse информацию. Делается это с помощью следующей функции:
BOOL DeleteReparseData(LPCTSTR src, DWORD reparse_tag) { REPARSE_GUID_DATA_BUFFER rd; HANDLE hDel = OpenLinkHandle(src); DWORD dwRet; if (hDel == INVALID_HANDLE_VALUE) { return FALSE; } ZeroMemory(&rd, REPARSE_GUID_DATA_BUFFER_HEADER_SIZE); rd.ReparseTag = reparse_tag; if (!DeviceIoControl(hDel, FSCTL_DELETE_REPARSE_POINT, &rd, REPARSE_GUID_DATA_BUFFER_HEADER_SIZE, NULL, 0, &dwRet, NULL)) { return FALSE; } CloseHandle(hDel); return TRUE; }
Копирование данных
Копирование данных заключается в получении reparse-данных в REPARSE_DATA_BUFFER или REPARSE_GUID_DATA_BUFFER, с помощью DeviceIoControl FSCTL_GET_REPARSE_POINT и записи этих данных в другой файл с помощью FSCTL_SET_REPARSE_POINT. Всё так же, как и при создании reparse point, только буфер формируется не вручную, а копируется из существующего файла.
По теме точек повторной обработки также есть следующее:
- Создание точки повторной обработки собственного типа.
- Стандартные функции WinAPI для создания символьных и жёстких ссылок в Windows.
Автор: амдф
Дата: 08.02.2011
Избранное
Остальное
По вопросам сотрудничества и другим вопросам по работе сайта пишите на cleogroup[собака]yandex.ru