Создать файл с режимом только для чтения в C - PullRequest
1 голос
/ 11 июня 2019

Я сохраняю некоторые данные в файл .txt, например:

void save_file()
{
    char *file_name = "my_file.txt";

    FILE *f = fopen(file_name, "w");
    if (f == NULL)
        return;

    // some fprintf instructions

    fclose(f);
}

Все отлично работает.Однако я хотел бы, чтобы этот файл имел свойство только для чтения.(Windows 10)

Есть ли решение моей проблемы с использованием только стандартных библиотек?

Ответы [ 2 ]

3 голосов
/ 11 июня 2019

Нет.Невозможно установить права доступа к файлам в чистом C, не прибегая к методам, специфичным для ОС.Я предполагаю, что под стандартными библиотеками вы подразумеваете средства, описанные в стандарте C.

2 голосов
/ 11 июня 2019

C не имеет концепции безопасности файлов из коробки.Поскольку вы используете Windows, вы можете использовать API-интерфейсы безопасности Windows, чтобы установить для ACL для определенных пользователей или групп значение «R» (только для чтения).Вот как это сделать для конкретного пользователя:

#include <Windows.h>
#include <aclapi.h>

DWORD WINAPI MakeUserAccessReadOnly(
    LPWSTR lpPath,
    SE_OBJECT_TYPE objType,
    LPWSTR lpUser
)
{
    PSECURITY_DESCRIPTOR pSD;
    PACL pCurrentACL, pNewACL;
    EXPLICIT_ACCESSW ea;
    DWORD dwError;

    dwError = GetNamedSecurityInfoW(lpPath, objType, DACL_SECURITY_INFORMATION, NULL, NULL, &pCurrentACL, NULL, &pSD);
    if (dwError != ERROR_SUCCESS)
    {
        return dwError;
    }

    ZeroMemory(&ea, sizeof(EXPLICIT_ACCESSW));
    ea.grfAccessPermissions = GENERIC_READ;
    ea.grfAccessMode = SET_ACCESS;
    ea.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
    ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
    ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
    ea.Trustee.ptstrName = lpUser;

    dwError = SetEntriesInAclW(1, &ea, pCurrentACL, &pNewACL);
    if (dwError != ERROR_SUCCESS)
    {
        return dwError;
    }

    dwError = SetNamedSecurityInfoW(lpPath, objType, DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION, NULL, NULL, pNewACL, NULL);
    LocalFree((HLOCAL)pNewACL);

    return dwError;
}

Затем можно вызвать функцию следующим образом:

MakeUserAccessReadOnly(L"C:\\Path\\FileToMakeReadOnly.ABC", SE_FILE_OBJECT, L"PC-NAME\UserName");

Затем, предположив, что пользователь с именем UserName не делает 'У него нет доступа на запись к файлу, скажем, через членство в группе, которая также имеет доступ на запись к файлу, у них будет только доступ на чтение к файлу.

...