Имеет ли значение, если процессы, выполняющие ввод-вывод файла, и процесс удаления файла являются локальными или удаленными?
интересно - как удаленная система может получить доступ к файлу (открыть, чтение-запись данных, удаление) на windows direct ?на самом деле это невозможно.нам нужен некоторый агент (сервер LANMan), работающий в локальной системе, который будет удаленными командами (отправлять, скажем, Network Redirector ) для выполнения локальных операций над файлом.так из представления файловой системы - все операции всегда локальные .
Способность удалять файлы при использовании функции
, которая, конечно, реализуется драйвером файловой системы, но этот драйвер написан для конкретной ОСи на основании этого правила.в то время как данные файловой системы на диске имеют общий формат (как результат, отформатированный диск (и записанные файлы) в одной ОС, могут быть прочитаны из другой ОС) - как драйвер файловой системы обрабатывает запросы, открывает, читает, записывает, удаляет файлы - этоОС зависит от.разные для разных ОС.на основании этого правила.поэтому формат данных на диске является общим и зависит только от файловой системы.но как эти данные читать / писать / удалять - уже определено ОС.
в Windows у нас есть следующие правила для удаления файлов:
Обычно файл помечен дляудаление фактически не удаляется до тех пор, пока все открытые дескрипторы файла не будут закрыты, а количество ссылок для файла равно нулю.При маркировке файла для удаления с использованием FILE_DISPOSITION_POSIX_SEMANTICS ссылка удаляется из видимого пространства имен, как только закрывается дескриптор удаления POSIX, но потоки данных файла остаются доступными для других существующих дескрипторов до тех пор, пока последний дескриптор не будетбыл закрыт.
, поэтому в общем случае файл не будет удален, пока не будет закрыт последний дескриптор к нему.файл стал недоступен после того, как мы попытались удалить его - больше не можем его открыть (мы получаем ошибку Запрошена операция без закрытия для файлового объекта с отложенным удалением. если попытаться сделать это, после того, как файл помечен какудалять).но если файл уже был открыт - мы все еще можем работать с ним этим дескриптором.Также файл не может быть удален, если в файле существует раздел - будет ошибка Была предпринята попытка удалить файл или каталог, которые невозможно удалить.
начните с win10 redstone1 build build FILE_DISPOSITION_POSIX_SEMANTICS
флаг, позволяющий удалить имя файла из видимого пространства имен, когда дескриптор удаления закрыт, но потоки данных файла остаются доступными для других существующих дескрипторов, пока не будет закрыт последний дескриптор
демонстрация теста кода Windows: (FILE_DISPOSITION_POSIX_SEMANTICS
, поддерживаемый ntfs, начинается только с _WIN32_WINNT_WIN10_RS1
. FileDispositionInfoEx
Информационный класс, также поддерживаемый, начинается только с _WIN32_WINNT_WIN10_RS1
. В предыдущей сборке мы просто получили не реализованную ошибку )
void print_error(PCSTR name)
{
PWSTR sz;
NTSTATUS status = RtlGetLastNtStatus();
if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_HMODULE,
GetModuleHandle(L"ntdll"), status, 0, (PWSTR)&sz, 0, 0))
{
DbgPrint("%s=%x\n%S\n", name, status, sz);
LocalFree(sz);
}
}
HANDLE OpenFile(PCWSTR lpFileName, DWORD dwDesiredAccess)
{
HANDLE hFile = CreateFileW(lpFileName, dwDesiredAccess, FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING, 0, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
print_error("OpenFile");
return 0;
}
return hFile;
}
void ReadTest(HANDLE hFile)
{
if (hFile)
{
ULONG dwBytes;
if (ReadFile(hFile, &dwBytes, sizeof(dwBytes), &dwBytes, 0))
{
DbgPrint("ReadFile=OK\n");
}
else
{
print_error("ReadFile");
}
}
}
void DeleteTest(PCWSTR lpFileName)
{
HANDLE hFile1, hFile2, hFile3;
if (hFile1 = OpenFile(lpFileName, DELETE))
{
hFile2 = OpenFile(lpFileName, FILE_GENERIC_READ);
FILE_DISPOSITION_INFO_EX fdi = { FILE_DISPOSITION_DELETE | FILE_DISPOSITION_POSIX_SEMANTICS };
if (!SetFileInformationByHandle(hFile1, FileDispositionInfoEx, &fdi, sizeof(fdi)))
{
print_error("SetFileInformationByHandle");
}
// file already not accessible here (open must fail) but visible
if (hFile3 = OpenFile(lpFileName, FILE_GENERIC_READ))
{
CloseHandle(hFile3);
}
ReadTest(hFile2);
// win10 rs1: file removed from the visible namespace here
CloseHandle(hFile1);
// are file still visible ?
if (hFile3 = OpenFile(lpFileName, FILE_GENERIC_READ))
{
CloseHandle(hFile3);
}
// are possible create new file with this name &
hFile3 = CreateFileW(lpFileName, DELETE,
FILE_SHARE_VALID_FLAGS, 0, CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, 0);
if (hFile3 == INVALID_HANDLE_VALUE)
{
print_error("CreateFile");
}
else
{
CloseHandle(hFile3);
DbgPrint("CreateFile OK\n");
}
ReadTest(hFile2);
if (hFile2)
{
CloseHandle(hFile2);
}
}
}
и вывод
OpenFile=c0000056
A non close operation has been requested of a file object with a delete pending.
ReadFile=OK
OpenFile=c0000034
Object Name not found.
CreateFile OK
ReadFile=OK