Как копировать точку повторной обработки или удалить 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