Стандартные 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);
Жёсткие ссылки
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
Избранное
Остальное
Лента atom