hex.pp.ua

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

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

система комментирования CACKLE

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


Разделы сайта
Главная
Блог
Native API
NTFS и ReFS
Микроконтроллеры
Справочник NTDLL
Коды NTSTATUS
Разное

Избранное
NTFS Stream Explorer
Native Shell
Тенгвар

Остальное
nvpnhcknn (архив)
English pages
Контакты

Ленты atom
Лента Atom сайта Лента Atom блога



При копировании материалов хорошим тоном будет указание авторства и ссылка на сайт.