oktava-studio.ru

Удаление и копирование reparse point



Как копировать точку повторной обработки или удалить 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, только буфер формируется не вручную, а копируется из существующего файла.

По теме точек повторной обработки также есть следующее:



Автор: амдф
Дата: 08.02.2011







Copyright © 2016- Программирование Native API и расширенные возможности NTFS
По вопросам сотрудничества и другим вопросам по работе сайта пишите на cleogroup[собака]yandex.ru