Удалить ссылку на файл без очистки бит только для чтения
У меня есть набор файлов с несколькими ссылками на них.
Файлы принадлежат TFS, но другие ссылки на них сделаны с ними. Как удалить дополнительные ссылки, не очищая бит readonly.
Можно предположить:
- Файлы имеют более одной ссылки на них
- Вы не удаляете имя, принадлежащее TFS
- Там нет потенциальных условий гонки
- У вас есть полный контроль над файлами ACL
- Машина не будет терять мощность, и ваша программа не будет убита, если это не займет слишком много времени.
Не безопасно предполагать:
- Установлен бит readonly (не устанавливайте его, если нет)
- Вы можете оставить бит readonly пустым, если вы столкнулись с ошибкой, и она была изначально установлена
Не переносите в superuser - если перенесено туда, ответ невозможен, потому что ни один стандартный инструмент не может сделать это.
В гипотетической системе * nix, в которой для удаления требуется разрешение на запись в файл, существует решение, включающее fchmod(). Однако система, демонстрирующая это поведение, является системой Windows.
3 ответа
Вы пытались включить SeBackupPrivilege и SeRestorePrivilege, которые позволяют администраторам ослабить многие проверки безопасности?
Вы можете найти эту ветку новостной группы полезной.
РЕДАКТИРОВАТЬ: Чтобы сделать это без привилегий и без создания условия гонки, вам потребуется поддержка транзакционной NTFS в Vista и выше. Кстати, вы можете установить атрибуты, используя дескриптор, передать FILE_BASIC_INFO в SetFileInformationByHandle, который может быть обработан, см. Примечания. Или вы можете использовать FindFirstFileName, чтобы найти другую жесткую ссылку на тот же файл, который не удаляется, и который можно установить только для чтения.
Спасибо Бену Фойгту:
#include <windows.h>
int main(int argc, char **argv)
{
while (*++argv) {
HANDLE h;
DWORD attrs;
attrs = GetFileAttributes(*argv);
SetFileAttributes(*argv, attrs & ~FILE_ATTRIBUTE_READONLY);
h = CreateFile(*argv, GENERIC_READ|GENERIC_WRITE, 7, NULL, OPEN_EXISTING,
FILE_FLAG_DELETE_ON_CLOSE, NULL);
SetFileAttributes(*argv, attrs);
if (h != INVALID_HANDLE_VALUE) {
CloseHandle(h);
}
}
}
Это невозможно Жесткая ссылка - это просто другое имя файла; у вас может быть много жестких ссылок, но есть только один базовый файловый объект (данные, дескриптор безопасности, атрибуты, время файла и т. д.). Если для файлового объекта установлен атрибут только для чтения, то для любых жестких ссылок по определению также будет установлен атрибут.