Удалить ссылку на файл без очистки бит только для чтения - PullRequest
4 голосов
/ 16 июня 2010

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

Файлы принадлежат системе контроля версий TFS, но на них сделаны другие ссылки. Как удалить дополнительные ссылки, не очищая бит readonly.

Можно предположить:

  • Файлы имеют более одной ссылки на них
  • Вы не удаляете имя, принадлежащее TFS
  • Потенциальные условия гонки отсутствуют
  • У вас есть полный контроль над файлами ACL
  • Машина не будет терять мощность, и ваша программа не будет убита, если это не займет слишком много времени.

Считать небезопасным:

  • Бит только для чтения установлен (не устанавливайте его, если нет)
  • Вы можете оставить бит readonly пустым, если вы столкнулись с ошибкой, и она была изначально установлена ​​

Не мигрировать в суперпользователя - если перенесено туда, ответ невозможен, потому что ни один стандартный инструмент не может сделать это.

В гипотетической * nix-системе, в которой для удаления требуется разрешение на запись в файл, существует решение, включающее fchmod (). Однако система, демонстрирующая это поведение, является системой Windows.

Ответы [ 3 ]

4 голосов
/ 18 июня 2010

Вы пытались включить SeBackupPrivilege и SeRestorePrivilege, которые позволяют администраторам ослабить многие проверки безопасности?

Вы можете найти эту ветку группы новостей полезной.

РЕДАКТИРОВАТЬ:Чтобы сделать это без привилегий и без создания условия гонки, вам понадобится поддержка транзакционной NTFS в Vista и выше.Кстати, вы можете установить атрибуты с помощью дескриптора, передать FILE_BASIC_INFO в SetFileInformationByHandle , который может быть обработан, см. Примечания.Или вы можете использовать FindFirstFileName, чтобы найти другую жесткую ссылку на тот же файл, который не удаляется, с которым можно установить только чтение.

4 голосов
/ 29 июня 2010

Спасибо Бену Фойгту:

#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);
        }
    }
}
2 голосов
/ 18 июня 2010

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

...