Символьные и жёсткие ссылки 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);

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



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


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