hex.pp.ua

Символьные и жёсткие ссылки Windows: стандартные функции

Стандартные API функции для создания ссылок в Windows




В этой статье речь идёт о стандартных WinAPI функциях для создания ссылок в Windows. О другом способе создания ссылок с помощью формирования и записи буфера reparse-данных читайте в статье Создание символьной ссылки Windows на C/C++.

С появлением в Windows Vista поддержки символьных ссылок в файловой системе NTFS, появилась и стандартная API-функция для их создания. Эта функция доступна также и в Windows Server 2008.

BOOL WINAPI CreateSymbolicLink(
  __in          LPCWSTR lpSymlinkFileName,
  __in          LPCWSTR lpTargetFileName,
  __in          DWORD dwFlags
);
  • lpSymlinkFileName — Имя символьной ссылки;
  • lpTargetFileName — Имя объекта, на который ссылается симлинк. Это может быть относительный путь к файлу или каталогу, или абсолютный путь, указывающий на файл, каталог или диск. Допустимо ссылаться также и на сетевой путь.
  • dwFlags — Флаги, управляющие созданием ссылки.

Флаги могут быть следующими:

  • 0x00 — ссылка на файл
  • 0x01 — SYMBOLIC_LINK_FLAG_DIRECTORY, ссылка на каталог.

Примеры использования функции

// ссылка на файл
CreateSymbolicLink(L"С:\\windows\\explorer.exe", L"file.exe", NULL); 
// ссылка на каталог
CreateSymbolicLink(L"С:\\windows\\system32", L"dir", 
                    SYMBOLIC_LINK_FLAG_DIRECTORY);

Жёсткие ссылки

Начиная с Windows 2000 и во всех последующих выпусках операционной системы существует функция для создания жёстких ссылок NTFS. Её использование крайне просто — всего два параметра (третий зарезервирован и всегда равен NULL). lpFileName — имя жёсткой ссылки, lpExistingFileName — имя существующего файла. Данная функция подходит для создания ссылок только на файлы.

BOOL WINAPI CreateHardLink(
  __in          LPCTSTR lpFileName,
  __in          LPCTSTR lpExistingFileName,
  LPSECURITY_ATTRIBUTES lpSecurityAttributes
);

Жёсткие ссылки по своей сути не ссылки. Это не отдельные объекты файловой системы, а просто ещё одно имя файла в таблице расположения файлов. Этим жёсткие ссылки отличаются от символьных.

Максимальное количество жёстких ссылок для одного файла в NTFS — 1024 ссылки. Напишем простую программу, чтобы проверить этот факт. Будем создавать в цикле жёсткие ссылки на файл, пока функция CreateHardLink не вернёт FALSE. После этого остановим цикл и выведем сообщение об ошибке, полученное по коду системной ошибки. Нам понадобится функция, выводящая текст ошибки по её коду.

void PrintWin32Error(DWORD ErrorCode)
{
  LPVOID lpMsgBuf;
 
  FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
                | FORMAT_MESSAGE_FROM_SYSTEM,
                NULL, ErrorCode, 
                MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
                (LPTSTR) &lpMsgBuf, 0, NULL);
  _tprintf(_T("%s\n"), lpMsgBuf);
 
  LocalFree(lpMsgBuf);  
}

Текст программы, создающей максимально возможное количество жёстких ссылок на файл:

int _tmain(int argc, _TCHAR* argv[])
{
  WCHAR pszNewLinkName[MAX_PATH];
  WCHAR *pszExistingFileName = L"file.dat";
  unsigned int i; 
 
  for (i = 0; i < 64000; i++) 
  {
    wsprintf(pszNewLinkName, L"link%d.dat", i);
 
    if (!CreateHardLink(pszNewLinkName, pszExistingFileName, NULL))
    {
      PrintWin32Error(GetLastError());
      wprintf(L"Stop at %d", i);
      break;
    }
  }
 
  return 0;
}

После выполнения этой программы мы увидим следующее:

An attempt was made to create more links on a file than the file system supports.

Stop at 1023

Будет создано 1024 файла с именами от !link0.dat до !link1023.dat, большее количество ссылок создать невозможно.

Точки монтирования и символьные связи

Точки монтирования разделов жёсткого диска и символьные связи (junctions) в Windows реализуются через один и тот же механизм. По сути это один вид ссылок. Но среди стандартных API-функций есть функция только для создания точек монтирования. Стандартной функции для создания символьных связей нет. Символьные связи создаются программно путём формирования reparse-буфера вручную, о чём идёт речь в статье "Создание символьной ссылки Windows на C/C++". В этой статье рассматриваются только стандартные функции для создания ссылок.

Для создания точек монтирования используется функция SetVolumeMountPoint:

BOOL WINAPI SetVolumeMountPoint(
  __in          LPCTSTR lpszVolumeMountPoint,
  __in          LPCTSTR lpszVolumeName
);
  • lpszVolumeMountPoint — Каталог, куда монтируется диск. Должен существовать к моменту вызова функции. Путь к каталогу должен оканчиваться на обратный слэш "\".
  • lpszVolumeName — Имя тома в формате "\\?\Volume{GUID}\". В таком виде имя тома можно получить из буквы диска путём использования функции GetVolumeNameForVolumeMountPoint.

Пример создания точки монтирования.

WCHAR pszNewLinkName[MAX_PATH];
WCHAR pszExistingFileName[MAX_PATH];
 
wsprintf(pszNewLinkName, L"dir\\");
 
GetVolumeNameForVolumeMountPoint(
  L"C:\\", pszExistingFileName, MAX_PATH
  );
SetVolumeMountPoint(pszNewLinkName, pszExistingFileName);

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

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

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


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

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

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

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



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