Удалить ссылку на файл без очистки бит только для чтения

У меня есть набор файлов с несколькими ссылками на них.

Файлы принадлежат 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);
        }
    }
}

Это невозможно Жесткая ссылка - это просто другое имя файла; у вас может быть много жестких ссылок, но есть только один базовый файловый объект (данные, дескриптор безопасности, атрибуты, время файла и т. д.). Если для файлового объекта установлен атрибут только для чтения, то для любых жестких ссылок по определению также будет установлен атрибут.

Другие вопросы по тегам