2 回答

TA貢獻(xiàn)1934條經(jīng)驗(yàn) 獲得超2個(gè)贊
在文件上執(zhí)行I / O和刪除文件的I / O進(jìn)程是本地的還是遠(yuǎn)程的,這有關(guān)系嗎?
有趣的是-遠(yuǎn)程系統(tǒng)如何直接在Windows上訪問文件(打開,讀寫數(shù)據(jù),刪除)?真的,這不可能。我們需要一些在本地系統(tǒng)中運(yùn)行的代理(LANMan服務(wù)器),該代理將通過遠(yuǎn)程命令(由Network Redirector發(fā)送)對(duì)文件進(jìn)行本地操作。因此,從文件系統(tǒng)視圖來看-所有操作始終是本地的。
能夠刪除正在使用的文件的功能
這當(dāng)然是由文件系統(tǒng)驅(qū)動(dòng)程序?qū)崿F(xiàn)的,但是該驅(qū)動(dòng)程序是為具體OS編寫的,并基于該規(guī)則。磁盤上的文件系統(tǒng)數(shù)據(jù)具有通用格式(因此,驅(qū)動(dòng)器在一個(gè)OS中格式化(和寫入的文件),可以從另一OS讀取)-文件系統(tǒng)驅(qū)動(dòng)程序如何處理請(qǐng)求,打開,讀取,寫入,刪除文件-這是特定于操作系統(tǒng)。針對(duì)不同的操作系統(tǒng)而有所不同。根據(jù)它的規(guī)則。因此磁盤上的數(shù)據(jù)格式是常見的,并且僅取決于文件系統(tǒng)。但是如何讀取/寫入/刪除此數(shù)據(jù)-已經(jīng)特定于操作系統(tǒng)。
在Windows中,我們有刪除文件的下一條規(guī)則:
通常,只有在關(guān)閉了該文件的所有打開句柄并且該文件的鏈接計(jì)數(shù)為零時(shí),才會(huì)真正刪除標(biāo)記為刪除的文件。當(dāng)使用FILE_DISPOSITION_POSIX_SEMANTICS將文件標(biāo)記為刪除時(shí) ,只要POSIX刪除句柄已關(guān)閉,該鏈接就會(huì)從可見的命名空間中刪除,但是其他現(xiàn)有句柄仍可訪問該文件的數(shù)據(jù)流,直到最后一個(gè)句柄已關(guān)閉。
因此,一般來說,文件不會(huì)被刪除,直到關(guān)閉文件的最后一個(gè)句柄為止。嘗試刪除文件后無法訪問該文件-無法再將其打開(我們收到錯(cuò)誤消息,請(qǐng)求對(duì)具有待處理刪除操作的文件對(duì)象執(zhí)行非關(guān)閉操作。如果嘗試這樣做,請(qǐng)?jiān)跇?biāo)記為刪除的文件之后進(jìn)行)。但是如果文件已經(jīng)打開-我們?nèi)匀豢梢酝ㄟ^此句柄使用它。如果文件上存在節(jié),也無法刪除文件-將是錯(cuò)誤試圖刪除無法刪除的文件或目錄。
從win10開始redstone1 build existFILE_DISPOSITION_POSIX_SEMANTICS標(biāo)志,當(dāng)刪除句柄關(guān)閉時(shí),該文件允許從可見的命名空間中刪除文件名,但是其他現(xiàn)有句柄仍可訪問文件的數(shù)據(jù)流,直到最后一個(gè)句柄關(guān)閉為止
Windows代碼測試演示:(FILE_DISPOSITION_POSIX_SEMANTICS由ntfs支持僅從開始_WIN32_WINNT_WIN10_RS1。FileDispositionInfoEx信息類也_WIN32_WINNT_WIN10_RS1僅從支持開始。在以前的構(gòu)建中,我們只是未實(shí)現(xiàn)錯(cuò)誤)
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

TA貢獻(xiàn)1852條經(jīng)驗(yàn) 獲得超1個(gè)贊
這取決于您如何定義文件系統(tǒng)和操作系統(tǒng)。通常,我了解在文件系統(tǒng)下數(shù)據(jù)存儲(chǔ)在設(shè)備上的組織方式。然后,操作系統(tǒng)負(fù)責(zé)數(shù)據(jù)和文件的I / O。特別是,如果您的腳本想要?jiǎng)h除文件,它將調(diào)用rm之類的實(shí)用程序并提供文件名。該實(shí)用程序是一個(gè)進(jìn)行適當(dāng)?shù)南到y(tǒng)調(diào)用的程序。該系統(tǒng)調(diào)用是在特權(quán)模式下執(zhí)行的操作系統(tǒng)的一部分。它實(shí)現(xiàn)了什么以及如何做(例如,應(yīng)該使用哪些驅(qū)動(dòng)程序?qū)DD塊標(biāo)記為在特定驅(qū)動(dòng)器上為空閑,或者應(yīng)該調(diào)用某些遠(yuǎn)程過程或涉及到samba服務(wù)器等。)因此,請(qǐng)回答您的問題1,我傾向于答案b。
添加回答
舉報(bào)